mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-01-27 15:49:47 +01:00
sync-in works for freshrss
This commit is contained in:
parent
2a1289e70a
commit
51e0f1675d
@ -30,7 +30,7 @@
|
||||
<url type="donation">https://martinrotter.github.io/donate/</url>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="3.8.4" date="2021-01-28"/>
|
||||
<release version="3.8.4" date="2021-01-29"/>
|
||||
</releases>
|
||||
<content_rating type="oars-1.0">
|
||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 9c10723bfbaf6cb85107d6ee16e0324e9e487749
|
||||
Subproject commit 47f4125753452eff8800dbd6600c5a05540b15d9
|
@ -1485,8 +1485,8 @@ bool DatabaseQueries::storeAccountTree(const QSqlDatabase& db, RootItem* tree_ro
|
||||
query_feed.setForwardOnly(true);
|
||||
query_category.prepare("INSERT INTO Categories (parent_id, title, account_id, custom_id) "
|
||||
"VALUES (:parent_id, :title, :account_id, :custom_id);");
|
||||
query_feed.prepare("INSERT INTO Feeds (title, icon, category, protected, update_type, update_interval, account_id, custom_id) "
|
||||
"VALUES (:title, :icon, :category, :protected, :update_type, :update_interval, :account_id, :custom_id);");
|
||||
query_feed.prepare("INSERT INTO Feeds (title, icon, url, category, protected, update_type, update_interval, account_id, custom_id) "
|
||||
"VALUES (:title, :icon, :url, :category, :protected, :update_type, :update_interval, :account_id, :custom_id);");
|
||||
|
||||
// Iterate all children.
|
||||
for (RootItem* child : tree_root->getSubTree()) {
|
||||
@ -1508,9 +1508,10 @@ bool DatabaseQueries::storeAccountTree(const QSqlDatabase& db, RootItem* tree_ro
|
||||
|
||||
query_feed.bindValue(QSL(":title"), feed->title());
|
||||
query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon()));
|
||||
query_feed.bindValue(QSL(":url"), feed->url());
|
||||
query_feed.bindValue(QSL(":category"), feed->parent()->id());
|
||||
query_feed.bindValue(QSL(":protected"), 0);
|
||||
query_feed.bindValue(QSL(":update_type"), (int) feed->autoUpdateType());
|
||||
query_feed.bindValue(QSL(":update_type"), int(feed->autoUpdateType()));
|
||||
query_feed.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval());
|
||||
query_feed.bindValue(QSL(":account_id"), account_id);
|
||||
query_feed.bindValue(QSL(":custom_id"), feed->customId());
|
||||
|
@ -255,8 +255,10 @@ Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db, const QList<MessageFilter*>& global_filters,
|
||||
int account_id, bool* ok) {
|
||||
Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
|
||||
const QList<MessageFilter*>& global_filters,
|
||||
int account_id,
|
||||
bool* ok) {
|
||||
Assignment feeds;
|
||||
|
||||
// All categories are now loaded.
|
||||
|
@ -18,6 +18,19 @@ quint64 TextFactory::s_encryptionKey = 0x0;
|
||||
|
||||
TextFactory::TextFactory() = default;
|
||||
|
||||
QColor TextFactory::generateColorFromText(const QString& text) {
|
||||
quint32 color = 0;
|
||||
|
||||
for (const QChar chr : text) {
|
||||
color += chr.unicode();
|
||||
}
|
||||
|
||||
color = QRandomGenerator(color).bounded(double(0xFFFFFF)) - 1;
|
||||
auto color_name = QSL("#%1").arg(color, 6, 16);
|
||||
|
||||
return QColor(color_name);
|
||||
}
|
||||
|
||||
int TextFactory::stringHeight(const QString& string, const QFontMetrics& metrics) {
|
||||
const int count_lines = string.split(QL1C('\n')).size();
|
||||
|
||||
|
@ -15,6 +15,7 @@ class TextFactory {
|
||||
TextFactory();
|
||||
|
||||
public:
|
||||
static QColor generateColorFromText(const QString& text);
|
||||
static int stringHeight(const QString& string, const QFontMetrics& metrics);
|
||||
static int stringWidth(const QString& string, const QFontMetrics& metrics);
|
||||
|
||||
|
@ -19,7 +19,7 @@ class QAction;
|
||||
class MessagesModel;
|
||||
class CacheForServiceRoot;
|
||||
|
||||
// Car here represents ID (int, primary key) of the item.
|
||||
// First item here represents ID (int, primary key) of the item.
|
||||
typedef QList<QPair<int, RootItem*>> Assignment;
|
||||
typedef QPair<int, RootItem*> AssignmentItem;
|
||||
typedef QPair<Message, RootItem::Importance> ImportanceChange;
|
||||
|
@ -1,6 +1,15 @@
|
||||
#ifndef GREADER_DEFINITIONS_H
|
||||
#define GREADER_DEFINITIONS_H
|
||||
|
||||
#define GREADER_UNLIMITED_BATCH_SIZE -1
|
||||
#define GREADER_UNLIMITED_BATCH_SIZE -1
|
||||
|
||||
// FreshRSS.
|
||||
#define FRESHRSS_BASE_URL_PATH "api/greader.php/"
|
||||
|
||||
// API.
|
||||
#define GREADER_API_CLIENT_LOGIN "accounts/ClientLogin?Email=%1&Passwd=%2"
|
||||
#define GREADER_API_TAG_LIST "reader/api/0/tag/list?output=json"
|
||||
#define GREADER_API_SUBSCRIPTION_LIST "reader/api/0/subscription/list?output=json"
|
||||
#define GREADER_API_STREAM_CONTENTS "reader/api/0/stream/contents/%1?output=json&n=%2"
|
||||
|
||||
#endif // GREADER_DEFINITIONS_H
|
||||
|
@ -4,14 +4,185 @@
|
||||
|
||||
#include "miscellaneous/application.h"
|
||||
#include "network-web/networkfactory.h"
|
||||
#include "services/abstract/category.h"
|
||||
#include "services/abstract/label.h"
|
||||
#include "services/abstract/labelsnode.h"
|
||||
#include "services/greader/definitions.h"
|
||||
#include "services/greader/greaderfeed.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
GreaderNetwork::GreaderNetwork(QObject* parent)
|
||||
: QObject(parent), m_service(GreaderServiceRoot::Service::FreshRss) {}
|
||||
: QObject(parent), m_service(GreaderServiceRoot::Service::FreshRss), m_username(QString()), m_password(QString()),
|
||||
m_baseUrl(QString()), m_batchSize(GREADER_UNLIMITED_BATCH_SIZE) {
|
||||
clearCredentials();
|
||||
}
|
||||
|
||||
QList<Message> GreaderNetwork::streamContents(ServiceRoot* root, const QString& stream_id, Feed::Status& error) {
|
||||
QString full_url = generateFullUrl(Operations::StreamContents).arg(stream_id, batchSize());
|
||||
auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||
|
||||
if (!ensureLogin(proxy)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QByteArray output_labels;
|
||||
auto result_labels = NetworkFactory::performNetworkOperation(full_url,
|
||||
timeout,
|
||||
{},
|
||||
output_labels,
|
||||
QNetworkAccessManager::Operation::GetOperation,
|
||||
{ authHeader() },
|
||||
false,
|
||||
{},
|
||||
{},
|
||||
proxy);
|
||||
|
||||
QList<Message> GreaderNetwork::messages(ServiceRoot* root, const QString& stream_id, Feed::Status& error) {
|
||||
return {};
|
||||
}
|
||||
|
||||
RootItem* GreaderNetwork::categoriesFeedsLabelsTree(bool obtain_icons, const QNetworkProxy& proxy) {
|
||||
QString full_url = generateFullUrl(Operations::TagList);
|
||||
auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||
|
||||
if (!ensureLogin(proxy)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QByteArray output_labels;
|
||||
auto result_labels = NetworkFactory::performNetworkOperation(full_url,
|
||||
timeout,
|
||||
{},
|
||||
output_labels,
|
||||
QNetworkAccessManager::Operation::GetOperation,
|
||||
{ authHeader() },
|
||||
false,
|
||||
{},
|
||||
{},
|
||||
proxy);
|
||||
|
||||
if (result_labels.first != QNetworkReply::NetworkError::NoError) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
full_url = generateFullUrl(Operations::SubscriptionList);
|
||||
QByteArray output_feeds;
|
||||
auto result_feeds = NetworkFactory::performNetworkOperation(full_url,
|
||||
timeout,
|
||||
{},
|
||||
output_feeds,
|
||||
QNetworkAccessManager::Operation::GetOperation,
|
||||
{ authHeader() },
|
||||
false,
|
||||
{},
|
||||
{},
|
||||
proxy);
|
||||
|
||||
if (result_feeds.first != QNetworkReply::NetworkError::NoError) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto root = decodeFeedCategoriesData(output_labels, output_feeds, obtain_icons);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
RootItem* GreaderNetwork::decodeFeedCategoriesData(const QString& categories, const QString& feeds, bool obtain_icons) {
|
||||
auto* parent = new RootItem();
|
||||
auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||
QJsonArray json = QJsonDocument::fromJson(categories.toUtf8()).object()["tags"].toArray();
|
||||
QMap<QString, RootItem*> cats;
|
||||
QList<RootItem*> lbls;
|
||||
|
||||
cats.insert(QString(), parent);
|
||||
|
||||
for (const QJsonValue& obj : json) {
|
||||
auto label = obj.toObject();
|
||||
|
||||
if (label["type"].toString() == QL1S("folder")) {
|
||||
QString label_id = label["id"].toString();
|
||||
|
||||
// We have label (not "state").
|
||||
auto* category = new Category();
|
||||
|
||||
category->setDescription(label["htmlUrl"].toString());
|
||||
category->setTitle(label_id.mid(label_id.lastIndexOf(QL1C('/')) + 1));
|
||||
category->setCustomId(label_id);
|
||||
|
||||
cats.insert(category->customId(), category);
|
||||
parent->appendChild(category);
|
||||
}
|
||||
else if (label["type"] == QL1S("tag")) {
|
||||
QString name_id = label["id"].toString();
|
||||
QString plain_name = QRegularExpression(".+\\/([^\\/]+)").match(name_id).captured(1);
|
||||
auto* new_lbl = new Label(plain_name, TextFactory::generateColorFromText(name_id));
|
||||
|
||||
new_lbl->setCustomId(name_id);
|
||||
lbls.append(new_lbl);
|
||||
}
|
||||
}
|
||||
|
||||
json = QJsonDocument::fromJson(feeds.toUtf8()).object()["subscriptions"].toArray();
|
||||
|
||||
for (const QJsonValue& obj : json) {
|
||||
auto subscription = obj.toObject();
|
||||
QString id = subscription["id"].toString();
|
||||
QString title = subscription["title"].toString();
|
||||
QString url = subscription["htmlUrl"].toString();
|
||||
QString parent_label;
|
||||
QJsonArray assigned_categories = subscription["categories"].toArray();
|
||||
|
||||
for (const QJsonValue& cat : assigned_categories) {
|
||||
QString potential_id = cat.toObject()["id"].toString();
|
||||
|
||||
if (potential_id.contains(QSL("/label/"))) {
|
||||
parent_label = potential_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We have label (not "state").
|
||||
auto* feed = new GreaderFeed();
|
||||
|
||||
feed->setDescription(url);
|
||||
feed->setUrl(url);
|
||||
feed->setTitle(title);
|
||||
feed->setCustomId(id);
|
||||
|
||||
if (obtain_icons) {
|
||||
QString icon_url = subscription["iconUrl"].toString();
|
||||
|
||||
if (!icon_url.isEmpty()) {
|
||||
QByteArray icon_data;
|
||||
|
||||
if (NetworkFactory::performNetworkOperation(icon_url, timeout,
|
||||
{}, icon_data,
|
||||
QNetworkAccessManager::Operation::GetOperation).first ==
|
||||
QNetworkReply::NetworkError::NoError) {
|
||||
// Icon downloaded, set it up.
|
||||
QPixmap icon_pixmap;
|
||||
|
||||
icon_pixmap.loadFromData(icon_data);
|
||||
feed->setIcon(QIcon(icon_pixmap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cats.contains(parent_label)) {
|
||||
cats[parent_label]->appendChild(feed);
|
||||
}
|
||||
}
|
||||
|
||||
auto* lblroot = new LabelsNode(parent);
|
||||
|
||||
lblroot->setChildItems(lbls);
|
||||
parent->appendChild(lblroot);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
QNetworkReply::NetworkError GreaderNetwork::clientLogin(const QNetworkProxy& proxy) {
|
||||
QString full_url = generateFullUrl(Operations::ClientLogin);
|
||||
auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||
@ -30,7 +201,38 @@ QNetworkReply::NetworkError GreaderNetwork::clientLogin(const QNetworkProxy& pro
|
||||
if (network_result.first == QNetworkReply::NetworkError::NoError) {
|
||||
// Save credentials.
|
||||
auto lines = QString::fromUtf8(output).replace(QSL("\r"), QString()).split('\n');
|
||||
int a = 5;
|
||||
|
||||
for (const QString& line : lines) {
|
||||
int eq = line.indexOf('=');
|
||||
|
||||
if (eq > 0) {
|
||||
QString id = line.mid(0, eq);
|
||||
|
||||
if (id == QSL("SID")) {
|
||||
m_authSid = line.mid(eq + 1);
|
||||
}
|
||||
else if (id == QSL("Auth")) {
|
||||
m_authAuth = line.mid(eq + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QRegularExpression exp("^(unused|none|null)$");
|
||||
|
||||
if (exp.match(m_authSid).hasMatch()) {
|
||||
m_authSid = QString();
|
||||
}
|
||||
|
||||
if (exp.match(m_authAuth).hasMatch()) {
|
||||
m_authAuth = QString();
|
||||
}
|
||||
|
||||
if (m_authAuth.isEmpty() ||
|
||||
(service() == GreaderServiceRoot::Service::FreshRss && m_authSid.isEmpty())) {
|
||||
clearCredentials();
|
||||
|
||||
return QNetworkReply::NetworkError::InternalServerError;
|
||||
}
|
||||
}
|
||||
|
||||
return network_result.first;
|
||||
@ -84,6 +286,25 @@ QString GreaderNetwork::serviceToString(GreaderServiceRoot::Service service) {
|
||||
}
|
||||
}
|
||||
|
||||
QPair<QByteArray, QByteArray> GreaderNetwork::authHeader() const {
|
||||
return { QSL("Authorization").toLocal8Bit(), QSL("GoogleLogin auth=%1").arg(m_authAuth).toLocal8Bit() };
|
||||
}
|
||||
|
||||
bool GreaderNetwork::ensureLogin(const QNetworkProxy& proxy) {
|
||||
if (m_authSid.isEmpty()) {
|
||||
auto login = clientLogin(proxy);
|
||||
|
||||
if (login != QNetworkReply::NetworkError::NoError) {
|
||||
qCriticalNN << LOGSEC_GREADER
|
||||
<< "Login failed with error:"
|
||||
<< QUOTE_W_SPACE_DOT(NetworkFactory::networkErrorText(login));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int GreaderNetwork::batchSize() const {
|
||||
return m_batchSize;
|
||||
}
|
||||
@ -92,18 +313,38 @@ void GreaderNetwork::setBatchSize(int batch_size) {
|
||||
m_batchSize = batch_size;
|
||||
}
|
||||
|
||||
void GreaderNetwork::clearCredentials() {
|
||||
m_authAuth = m_authSid = QString();
|
||||
}
|
||||
|
||||
QString GreaderNetwork::sanitizedBaseUrl() const {
|
||||
if (m_baseUrl.endsWith('/')) {
|
||||
return m_baseUrl;
|
||||
auto base_url = m_baseUrl;
|
||||
|
||||
if (!base_url.endsWith('/')) {
|
||||
base_url = base_url + QL1C('/');
|
||||
}
|
||||
else {
|
||||
return m_baseUrl + QL1C('/');
|
||||
|
||||
switch (m_service) {
|
||||
case GreaderServiceRoot::Service::FreshRss:
|
||||
base_url += FRESHRSS_BASE_URL_PATH;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return base_url;
|
||||
}
|
||||
|
||||
QString GreaderNetwork::generateFullUrl(GreaderNetwork::Operations operation) const {
|
||||
switch (operation) {
|
||||
case Operations::ClientLogin:
|
||||
return sanitizedBaseUrl() + QSL("accounts/ClientLogin?Email=%1&Passwd=%2").arg(username(), password());
|
||||
return sanitizedBaseUrl() + QSL(GREADER_API_CLIENT_LOGIN).arg(username(), password());
|
||||
|
||||
case Operations::TagList:
|
||||
return sanitizedBaseUrl() + GREADER_API_TAG_LIST;
|
||||
|
||||
case Operations::SubscriptionList:
|
||||
return sanitizedBaseUrl() + GREADER_API_SUBSCRIPTION_LIST;
|
||||
}
|
||||
}
|
||||
|
@ -14,18 +14,24 @@ class GreaderNetwork : public QObject {
|
||||
|
||||
public:
|
||||
enum class Operations {
|
||||
ClientLogin
|
||||
ClientLogin,
|
||||
TagList,
|
||||
SubscriptionList,
|
||||
StreamContents
|
||||
};
|
||||
|
||||
explicit GreaderNetwork(QObject* parent = nullptr);
|
||||
|
||||
// Network operations.
|
||||
QList<Message> messages(ServiceRoot* root, const QString& stream_id, Feed::Status& error);
|
||||
// Stream contents for a feed/label/etc.
|
||||
QList<Message> streamContents(ServiceRoot* root, const QString& stream_id, Feed::Status& error);
|
||||
|
||||
// Downloads and structures full tree for sync-in.
|
||||
RootItem* categoriesFeedsLabelsTree(bool obtain_icons, const QNetworkProxy& proxy);
|
||||
|
||||
// Performs client login, if successful, then saves SID, LSID and Auth.
|
||||
QNetworkReply::NetworkError clientLogin(const QNetworkProxy& proxy);
|
||||
|
||||
// Metadata.
|
||||
// Getters/setters.
|
||||
GreaderServiceRoot::Service service() const;
|
||||
void setService(const GreaderServiceRoot::Service& service);
|
||||
|
||||
@ -38,12 +44,20 @@ class GreaderNetwork : public QObject {
|
||||
QString baseUrl() const;
|
||||
void setBaseUrl(const QString& base_url);
|
||||
|
||||
static QString serviceToString(GreaderServiceRoot::Service service);
|
||||
|
||||
int batchSize() const;
|
||||
void setBatchSize(int batch_size);
|
||||
|
||||
void clearCredentials();
|
||||
|
||||
static QString serviceToString(GreaderServiceRoot::Service service);
|
||||
|
||||
private:
|
||||
QPair<QByteArray, QByteArray> authHeader() const;
|
||||
|
||||
// Make sure we are logged in and if we are not, return error.
|
||||
bool ensureLogin(const QNetworkProxy& proxy);
|
||||
|
||||
RootItem* decodeFeedCategoriesData(const QString& categories, const QString& feeds, bool obtain_icons);
|
||||
QString sanitizedBaseUrl() const;
|
||||
QString generateFullUrl(Operations operation) const;
|
||||
|
||||
@ -53,6 +67,8 @@ class GreaderNetwork : public QObject {
|
||||
QString m_password;
|
||||
QString m_baseUrl;
|
||||
int m_batchSize;
|
||||
QString m_authSid;
|
||||
QString m_authAuth;
|
||||
};
|
||||
|
||||
#endif // GREADERNETWORK_H
|
||||
|
@ -131,16 +131,7 @@ void GreaderServiceRoot::saveAccountDataToDatabase(bool creating_new) {
|
||||
}
|
||||
|
||||
RootItem* GreaderServiceRoot::obtainNewTreeForSyncIn() const {
|
||||
return nullptr;
|
||||
|
||||
/*OwnCloudGetFeedsCategoriesResponse feed_cats_response = m_network->feedsCategories(networkProxy());
|
||||
|
||||
if (feed_cats_response.networkError() == QNetworkReply::NetworkError::NoError) {
|
||||
return feed_cats_response.feedsCategories(true);
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}*/
|
||||
return m_network->categoriesFeedsLabelsTree(true, networkProxy());
|
||||
}
|
||||
|
||||
void GreaderServiceRoot::loadFromDatabase() {
|
||||
|
@ -14,14 +14,13 @@ GreaderAccountDetails::GreaderAccountDetails(QWidget* parent) : QWidget(parent)
|
||||
for (auto serv : { GreaderServiceRoot::Service::FreshRss,
|
||||
GreaderServiceRoot::Service::Bazqux,
|
||||
GreaderServiceRoot::Service::TheOldReader }) {
|
||||
m_ui.m_cmbService->addItem(GreaderNetwork::serviceToString(serv),
|
||||
QVariant::fromValue(serv));
|
||||
m_ui.m_cmbService->addItem(GreaderNetwork::serviceToString(serv), QVariant::fromValue(serv));
|
||||
}
|
||||
|
||||
m_ui.m_lblTestResult->label()->setWordWrap(true);
|
||||
m_ui.m_txtPassword->lineEdit()->setPlaceholderText(tr("Password for your Nextcloud account"));
|
||||
m_ui.m_txtUsername->lineEdit()->setPlaceholderText(tr("Username for your Nextcloud account"));
|
||||
m_ui.m_txtUrl->lineEdit()->setPlaceholderText(tr("URL of your Nextcloud server, without any API path"));
|
||||
m_ui.m_txtPassword->lineEdit()->setPlaceholderText(tr("Password for your account"));
|
||||
m_ui.m_txtUsername->lineEdit()->setPlaceholderText(tr("Username for your account"));
|
||||
m_ui.m_txtUrl->lineEdit()->setPlaceholderText(tr("URL of your server, without any service-specific path"));
|
||||
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Information,
|
||||
tr("No test done yet."),
|
||||
tr("Here, results of connection test are shown."));
|
||||
@ -77,6 +76,7 @@ void GreaderAccountDetails::performTest(const QNetworkProxy& custom_proxy) {
|
||||
factory.setPassword(m_ui.m_txtPassword->lineEdit()->text());
|
||||
factory.setBaseUrl(m_ui.m_txtUrl->lineEdit()->text());
|
||||
factory.setService(service());
|
||||
factory.clearCredentials();
|
||||
|
||||
auto result = factory.clientLogin(custom_proxy);
|
||||
|
||||
|
@ -145,18 +145,8 @@ QList<RootItem*> InoreaderNetworkFactory::getLabels() {
|
||||
|
||||
if (lbl_obj["type"] == QL1S("tag")) {
|
||||
QString name_id = lbl_obj["id"].toString();
|
||||
QString id = QRegularExpression("user\\/(\\d+)\\/").match(name_id).captured(1);
|
||||
QString plain_name = QRegularExpression(".+\\/([^\\/]+)").match(name_id).captured(1);
|
||||
quint32 color = 0;
|
||||
|
||||
for (const QChar chr : name_id) {
|
||||
color += chr.unicode();
|
||||
}
|
||||
|
||||
color = QRandomGenerator(color).bounded(double(0xFFFFFF)) - 1;
|
||||
|
||||
auto color_name = QSL("#%1").arg(color, 6, 16);
|
||||
auto* new_lbl = new Label(plain_name, QColor(color_name));
|
||||
auto* new_lbl = new Label(plain_name, TextFactory::generateColorFromText(name_id));
|
||||
|
||||
new_lbl->setCustomId(name_id);
|
||||
lbls.append(new_lbl);
|
||||
|
Loading…
x
Reference in New Issue
Block a user