From 571f709b50222be19490b60e41ba437036046a7f Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 11 Apr 2023 00:36:41 +0200 Subject: [PATCH] FeedReader: The feed can be used as source for board --- plugins/FeedReader/FeedReaderPlugin.cpp | 2 +- plugins/FeedReader/gui/AddFeedDialog.cpp | 214 ++++++++++++-- plugins/FeedReader/gui/AddFeedDialog.h | 12 +- plugins/FeedReader/gui/AddFeedDialog.ui | 116 ++++++-- .../gui/FeedReaderMessageWidget.cpp | 14 +- .../FeedReader/gui/FeedReaderStringDefs.cpp | 18 +- plugins/FeedReader/interface/rsFeedReader.h | 13 +- plugins/FeedReader/lang/FeedReader_en.ts | 90 ++++-- plugins/FeedReader/services/p3FeedReader.cc | 263 +++++++++++++++++- plugins/FeedReader/services/p3FeedReader.h | 10 +- .../FeedReader/services/p3FeedReaderThread.cc | 26 +- .../FeedReader/services/rsFeedReaderItems.cc | 8 +- .../FeedReader/services/rsFeedReaderItems.h | 31 ++- 13 files changed, 704 insertions(+), 113 deletions(-) diff --git a/plugins/FeedReader/FeedReaderPlugin.cpp b/plugins/FeedReader/FeedReaderPlugin.cpp index 24b602f9c..bc44a3036 100644 --- a/plugins/FeedReader/FeedReaderPlugin.cpp +++ b/plugins/FeedReader/FeedReaderPlugin.cpp @@ -92,7 +92,7 @@ void FeedReaderPlugin::setInterfaces(RsPlugInInterfaces &interfaces) { mInterfaces = interfaces; - mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums); + mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums, mInterfaces.mPosted); rsFeedReader = mFeedReader; mNotify = new FeedReaderNotify(); diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index 19d02d968..c99b29b7a 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -30,9 +30,11 @@ #include "gui/common/UIStateHelper.h" #include +#include #include -#define TOKEN_TYPE_FORUM_GROUPS 1 +#define TOKEN_TYPE_FORUM_GROUPS 1 +#define TOKEN_TYPE_POSTED_GROUPS 2 AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent) : QDialog(parent, Qt::Window), mFeedReader(feedReader), mNotify(notify), ui(new Ui::AddFeedDialog) @@ -47,9 +49,12 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, mStateHelper->addWidget(TOKEN_TYPE_FORUM_GROUPS, ui->forumComboBox, UISTATE_LOADING_DISABLED); mStateHelper->addWidget(TOKEN_TYPE_FORUM_GROUPS, ui->buttonBox->button(QDialogButtonBox::Ok), UISTATE_LOADING_DISABLED); + mStateHelper->addWidget(TOKEN_TYPE_POSTED_GROUPS, ui->postedComboBox, UISTATE_LOADING_DISABLED); + mStateHelper->addWidget(TOKEN_TYPE_POSTED_GROUPS, ui->buttonBox->button(QDialogButtonBox::Ok), UISTATE_LOADING_DISABLED); /* Setup TokenQueue */ - mTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mForumTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mPostedTokenQueue = new TokenQueue(rsPosted->getTokenService(), this); /* Connect signals */ connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(createFeed())); @@ -59,18 +64,23 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, connect(ui->useStandardStorageTimeCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardStorageTimeToggled())); connect(ui->useStandardUpdateInterval, SIGNAL(toggled(bool)), this, SLOT(useStandardUpdateIntervalToggled())); connect(ui->useStandardProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardProxyToggled())); - connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + connect(ui->typeForumCheckBox, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + connect(ui->typePostedCheckBox, SIGNAL(toggled(bool)), this, SLOT(typePostedToggled())); + connect(ui->typeLocalCheckBox, SIGNAL(toggled(bool)), this, SLOT(typeLocalToggled())); + connect(ui->postedFirstImageCheckBox, SIGNAL(toggled(bool)), this, SLOT(postedFirstImageToggled())); connect(ui->previewButton, SIGNAL(clicked()), this, SLOT(preview())); /* currently only for local feeds */ - connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumToggled())); + connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumAndPostedToggled())); connect(ui->urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->useInfoFromFeedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); - connect(ui->typeLocalRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); - connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeLocalCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeForumCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); connect(ui->forumComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(validate())); + connect(ui->typePostedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->postedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(validate())); connect(ui->clearCachePushButton, SIGNAL(clicked()), this, SLOT(clearMessageCache())); @@ -79,13 +89,22 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, ui->activatedCheckBox->setChecked(true); mStateHelper->setWidgetEnabled(ui->forumComboBox, false); + mStateHelper->setWidgetEnabled(ui->postedComboBox, false); ui->useInfoFromFeedCheckBox->setChecked(true); ui->updateForumInfoCheckBox->setEnabled(false); ui->updateForumInfoCheckBox->setChecked(true); + ui->updatePostedInfoCheckBox->setEnabled(false); + ui->updatePostedInfoCheckBox->setChecked(true); + ui->postedFirstImageCheckBox->setEnabled(false); + ui->postedFirstImageCheckBox->setChecked(false); + ui->postedOnlyImageCheckBox->setEnabled(false); + ui->postedOnlyImageCheckBox->setChecked(false); ui->useAuthenticationCheckBox->setChecked(false); ui->useStandardStorageTimeCheckBox->setChecked(true); ui->useStandardUpdateInterval->setChecked(true); ui->useStandardProxyCheckBox->setChecked(true); + ui->embedImagesCheckBox->setChecked(true); + ui->saveCompletePageCheckBox->setEnabled(false); /* not yet supported */ ui->authenticationGroupBox->setEnabled(false); @@ -98,6 +117,9 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, /* fill own forums */ requestForumGroups(); + /* fill own posted */ + requestPostedGroups(); + validate(); ui->urlLineEdit->setFocus(); @@ -112,7 +134,8 @@ AddFeedDialog::~AddFeedDialog() processSettings(false); delete(ui); - delete(mTokenQueue); + delete(mForumTokenQueue); + delete(mPostedTokenQueue); } void AddFeedDialog::processSettings(bool load) @@ -161,18 +184,65 @@ void AddFeedDialog::useStandardProxyToggled() void AddFeedDialog::typeForumToggled() { - bool checked = ui->typeForumRadio->isChecked(); + bool checked = ui->typeForumCheckBox->isChecked(); mStateHelper->setWidgetEnabled(ui->forumComboBox, checked); ui->updateForumInfoCheckBox->setEnabled(checked); + + if (checked) { + ui->typeLocalCheckBox->setChecked(false); + } } -void AddFeedDialog::denyForumToggled() +void AddFeedDialog::postedFirstImageToggled() +{ + bool checked = ui->postedFirstImageCheckBox->isChecked(); + ui->postedOnlyImageCheckBox->setEnabled(checked); + + if (!checked) { + ui->postedOnlyImageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::typePostedToggled() +{ + bool checked = ui->typePostedCheckBox->isChecked(); + mStateHelper->setWidgetEnabled(ui->postedComboBox, checked); + ui->updatePostedInfoCheckBox->setEnabled(checked); + ui->postedFirstImageCheckBox->setEnabled(checked); + + if (checked) { + ui->typeLocalCheckBox->setChecked(false); + }else { + ui->postedFirstImageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::typeLocalToggled() +{ + bool checked = ui->typeLocalCheckBox->isChecked(); + if (checked) { + mStateHelper->setWidgetEnabled(ui->forumComboBox, false); + mStateHelper->setWidgetEnabled(ui->postedComboBox, false); + ui->typeForumCheckBox->setChecked(false); + ui->typePostedCheckBox->setChecked(false); + ui->saveCompletePageCheckBox->setEnabled(true); + } else { + ui->saveCompletePageCheckBox->setEnabled(false); + ui->saveCompletePageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::denyForumAndPostedToggled() { if (ui->saveCompletePageCheckBox->isChecked()) { - ui->typeForumRadio->setEnabled(false); - ui->typeLocalRadio->setChecked(true); + ui->typeForumCheckBox->setEnabled(false); + ui->typeForumCheckBox->setChecked(false); + ui->typePostedCheckBox->setEnabled(false); + ui->typePostedCheckBox->setChecked(false); + ui->typeLocalCheckBox->setChecked(true); } else { - ui->typeForumRadio->setEnabled(true); + ui->typeForumCheckBox->setEnabled(true); + ui->typePostedCheckBox->setEnabled(true); } } @@ -189,11 +259,15 @@ void AddFeedDialog::validate() ui->previewButton->setEnabled(ok); - if (!ui->typeLocalRadio->isChecked() && !ui->typeForumRadio->isChecked()) { + if (!ui->typeLocalCheckBox->isChecked() && !ui->typeForumCheckBox->isChecked() && !ui->typePostedCheckBox->isChecked()) { ok = false; } - if (ui->typeForumRadio->isChecked() && ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().isEmpty()) { + if (ui->typeForumCheckBox->isChecked() && ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().isEmpty()) { + ok = false; + } + + if (ui->typePostedCheckBox->isChecked() && ui->postedComboBox->itemData(ui->postedComboBox->currentIndex()).toString().isEmpty()) { ok = false; } @@ -224,20 +298,31 @@ bool AddFeedDialog::fillFeed(uint32_t feedId) ui->urlLineEdit->setText(QString::fromUtf8(feedInfo.url.c_str())); ui->useInfoFromFeedCheckBox->setChecked(feedInfo.flag.infoFromFeed); ui->updateForumInfoCheckBox->setChecked(feedInfo.flag.updateForumInfo); + ui->updatePostedInfoCheckBox->setChecked(feedInfo.flag.updatePostedInfo); + ui->postedFirstImageCheckBox->setChecked(feedInfo.flag.postedFirstImage); + ui->postedOnlyImageCheckBox->setChecked(feedInfo.flag.postedOnlyImage); ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated); ui->embedImagesCheckBox->setChecked(feedInfo.flag.embedImages); ui->saveCompletePageCheckBox->setChecked(feedInfo.flag.saveCompletePage); ui->descriptionPlainTextEdit->setPlainText(QString::fromUtf8(feedInfo.description.c_str())); - if (feedInfo.flag.forum) { - mStateHelper->setWidgetEnabled(ui->forumComboBox, true); - ui->typeForumRadio->setChecked(true); - ui->saveCompletePageCheckBox->setEnabled(false); + if (feedInfo.flag.forum || feedInfo.flag.posted) { + if (feedInfo.flag.forum) { + mStateHelper->setWidgetEnabled(ui->forumComboBox, true); + ui->typeForumCheckBox->setChecked(true); - setActiveForumId(feedInfo.forumId); + setActiveForumId(feedInfo.forumId); + } + if (feedInfo.flag.posted) { + mStateHelper->setWidgetEnabled(ui->postedComboBox, true); + ui->typePostedCheckBox->setChecked(true); + + setActivePostedId(feedInfo.postedId); + } + ui->saveCompletePageCheckBox->setEnabled(false); } else { - ui->typeLocalRadio->setChecked(true); + ui->typeLocalCheckBox->setChecked(true); mStateHelper->setWidgetEnabled(ui->forumComboBox, false); } @@ -286,6 +371,21 @@ void AddFeedDialog::setActiveForumId(const std::string &forumId) } } +void AddFeedDialog::setActivePostedId(const std::string &postedId) +{ + if (mStateHelper->isLoading(TOKEN_TYPE_POSTED_GROUPS)) { + mFillPostedId = postedId; + return; + } + + int index = ui->postedComboBox->findData(QString::fromStdString(postedId)); + if (index >= 0) { + ui->postedComboBox->setCurrentIndex(index); + } else { + ui->postedComboBox->setCurrentIndex(0); + } +} + void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) { feedInfo.parentId = mParentId; @@ -294,18 +394,27 @@ void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) feedInfo.url = ui->urlLineEdit->text().toUtf8().constData(); feedInfo.flag.infoFromFeed = ui->useInfoFromFeedCheckBox->isChecked(); feedInfo.flag.updateForumInfo = ui->updateForumInfoCheckBox->isChecked() && ui->updateForumInfoCheckBox->isEnabled(); + feedInfo.flag.updatePostedInfo = ui->updatePostedInfoCheckBox->isChecked() && ui->updatePostedInfoCheckBox->isEnabled(); + feedInfo.flag.postedFirstImage = ui->postedFirstImageCheckBox->isChecked() && ui->postedFirstImageCheckBox->isEnabled(); + feedInfo.flag.postedOnlyImage = ui->postedOnlyImageCheckBox->isChecked() && ui->postedOnlyImageCheckBox->isEnabled(); feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked(); feedInfo.flag.embedImages = ui->embedImagesCheckBox->isChecked(); feedInfo.flag.saveCompletePage = ui->saveCompletePageCheckBox->isChecked(); feedInfo.description = ui->descriptionPlainTextEdit->toPlainText().toUtf8().constData(); - feedInfo.flag.forum = ui->typeForumRadio->isChecked(); + feedInfo.flag.forum = ui->typeForumCheckBox->isChecked(); if (feedInfo.flag.forum) { feedInfo.forumId = ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().toStdString(); } + feedInfo.flag.posted = ui->typePostedCheckBox->isChecked(); + + if (feedInfo.flag.posted) { + feedInfo.postedId = ui->postedComboBox->itemData(ui->postedComboBox->currentIndex()).toString().toStdString(); + } + feedInfo.flag.authentication = ui->useAuthenticationCheckBox->isChecked(); feedInfo.user = ui->userLineEdit->text().toUtf8().constData(); feedInfo.password = ui->passwordLineEdit->text().toUtf8().constData(); @@ -382,10 +491,10 @@ void AddFeedDialog::requestForumGroups() RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS); + mForumTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS); uint32_t token; - mTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_FORUM_GROUPS); + mForumTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_FORUM_GROUPS); } void AddFeedDialog::loadForumGroups(const uint32_t &token) @@ -416,9 +525,50 @@ void AddFeedDialog::loadForumGroups(const uint32_t &token) } } +void AddFeedDialog::requestPostedGroups() +{ + mStateHelper->setLoading(TOKEN_TYPE_POSTED_GROUPS, true); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + mPostedTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_POSTED_GROUPS); + + uint32_t token; + mPostedTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_POSTED_GROUPS); +} + +void AddFeedDialog::loadPostedGroups(const uint32_t &token) +{ + std::vector groups; + rsPosted->getGroupData(token, groups); + + ui->postedComboBox->clear(); + + for (std::vector::iterator it = groups.begin(); it != groups.end(); ++it) { + const RsPostedGroup &group = *it; + + /* show only own posted */ + if (IS_GROUP_PUBLISHER(group.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(group.mMeta.mSubscribeFlags) && !group.mMeta.mAuthorId.isNull()) { + ui->postedComboBox->addItem(QString::fromUtf8(group.mMeta.mGroupName.c_str()), QString::fromStdString(group.mMeta.mGroupId.toStdString())); + } + } + + /* insert empty item */ + ui->postedComboBox->insertItem(0, "", ""); + ui->postedComboBox->setCurrentIndex(0); + + mStateHelper->setLoading(TOKEN_TYPE_POSTED_GROUPS, false); + + if (!mFillPostedId.empty()) { + setActivePostedId(mFillPostedId); + mFillPostedId.clear(); + } +} + void AddFeedDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { - if (queue == mTokenQueue) + if (queue == mForumTokenQueue) { /* now switch on req */ switch(req.mUserType) @@ -433,4 +583,20 @@ void AddFeedDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req } } + + if (queue == mPostedTokenQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case TOKEN_TYPE_POSTED_GROUPS: + loadPostedGroups(req.mToken); + break; + + default: + std::cerr << "AddFeedDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + + } + } } diff --git a/plugins/FeedReader/gui/AddFeedDialog.h b/plugins/FeedReader/gui/AddFeedDialog.h index 111238d33..e557580e1 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.h +++ b/plugins/FeedReader/gui/AddFeedDialog.h @@ -53,7 +53,10 @@ private slots: void useStandardUpdateIntervalToggled(); void useStandardProxyToggled(); void typeForumToggled(); - void denyForumToggled(); + void postedFirstImageToggled(); + void typePostedToggled(); + void typeLocalToggled(); + void denyForumAndPostedToggled(); void validate(); void createFeed(); void preview(); @@ -63,9 +66,12 @@ private: void processSettings(bool load); void getFeedInfo(FeedInfo &feedInfo); void setActiveForumId(const std::string &forumId); + void setActivePostedId(const std::string &postedId); void requestForumGroups(); void loadForumGroups(const uint32_t &token); + void requestPostedGroups(); + void loadPostedGroups(const uint32_t &token); private: RsFeedReader *mFeedReader; @@ -73,13 +79,15 @@ private: uint32_t mFeedId; uint32_t mParentId; std::string mFillForumId; + std::string mFillPostedId; RsFeedTransformationType mTransformationType; std::list mXPathsToUse; std::list mXPathsToRemove; std::string mXslt; - TokenQueue *mTokenQueue; + TokenQueue *mForumTokenQueue; + TokenQueue *mPostedTokenQueue; UIStateHelper *mStateHelper; Ui::AddFeedDialog *ui; diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index a10cec8a4..f3bcaf85f 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -50,7 +50,7 @@ Type - + 6 @@ -63,27 +63,75 @@ 6 - - - - - - Forum - - - - - - - + + + + + 0 + 0 + + + + Forum + + - - + + + + + Local Feed + + + + + + Update forum information + + + + + + + + + + + + Board + + + + + + + + + Update board information + + + + + + + Only image + + + + + + + Use first image as board image + + + + + @@ -309,7 +357,6 @@ 11 - 75 true true @@ -377,13 +424,6 @@ - - - - Update forum information - - - @@ -398,6 +438,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -423,22 +476,31 @@ urlLineEdit nameLineEdit descriptionPlainTextEdit - typeForumRadio + typeForumCheckBox forumComboBox + updateForumInfoCheckBox + typePostedCheckBox + postedComboBox + updatePostedInfoCheckBox + postedFirstImageCheckBox + checkBox + typeLocalCheckBox activatedCheckBox useInfoFromFeedCheckBox - updateForumInfoCheckBox + embedImagesCheckBox + saveCompletePageCheckBox + previewButton useAuthenticationCheckBox userLineEdit passwordLineEdit useStandardStorageTimeCheckBox + clearCachePushButton storageTimeSpinBox useStandardUpdateInterval updateIntervalSpinBox useStandardProxyCheckBox proxyAddressLineEdit proxyPortSpinBox - buttonBox diff --git a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp index 1550bc636..96198f400 100644 --- a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp +++ b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp @@ -245,9 +245,19 @@ void FeedReaderMessageWidget::setFeedId(uint32_t feedId) ui->msgReadAllButton->setEnabled(false); ui->msgTreeWidget->setPlaceholderText(""); } else { - if (mFeedInfo.flag.forum) { + if (mFeedInfo.flag.forum || mFeedInfo.flag.posted) { ui->msgReadAllButton->setEnabled(false); - ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum")); + + if (mFeedInfo.flag.forum && mFeedInfo.flag.posted) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum and the board")); + } else { + if (mFeedInfo.flag.forum) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum")); + } + if (mFeedInfo.flag.posted) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the board")); + } + } } else { ui->msgReadAllButton->setEnabled(true); ui->msgTreeWidget->setPlaceholderText(""); diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp index 99c537498..fefb3ed32 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp @@ -109,9 +109,9 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT: errorText = QApplication::translate("FeedReaderStringDefs", "Unknown XML format"); break; - case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: - errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); - break; +// case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: +// errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); +// break; case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND: errorText = QApplication::translate("FeedReaderStringDefs", "Forum not found"); break; @@ -121,6 +121,18 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR: errorText = QApplication::translate("FeedReaderStringDefs", "Forum has no author"); break; +// case RS_FEED_ERRORSTATE_PROCESS_POSTED_CREATE: +// errorText = QApplication::translate("FeedReaderStringDefs", "Can't create board"); +// break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND: + errorText = QApplication::translate("FeedReaderStringDefs", "Board not found"); + break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN: + errorText = QApplication::translate("FeedReaderStringDefs", "You are not admin of the board"); + break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR: + errorText = QApplication::translate("FeedReaderStringDefs", "Board has no author"); + break; case RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR: errorText = QApplication::translate("FeedReaderStringDefs", "Can't read html"); diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index bf524ad0c..7158d29ee 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -42,10 +42,14 @@ enum RsFeedReaderErrorState { /* process */ RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT = 51, - RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, +// RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND = 101, RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102, RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR = 103, +// RS_FEED_ERRORSTATE_PROCESS_POSTED_CREATE = 104, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND = 105, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN = 106, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR = 107, RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR = 150, RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR = 151, @@ -102,6 +106,8 @@ public: flag.deactivated = false; flag.forum = false; flag.updateForumInfo = false; + flag.posted = false; + flag.updatePostedInfo = false; flag.embedImages = false; flag.saveCompletePage = false; flag.preview = false; @@ -122,6 +128,7 @@ public: time_t lastUpdate; uint32_t storageTime; std::string forumId; + std::string postedId; WorkState workstate; RsFeedReaderErrorState errorState; std::string errorString; @@ -141,6 +148,10 @@ public: bool deactivated : 1; bool forum : 1; bool updateForumInfo : 1; + bool posted : 1; + bool updatePostedInfo : 1; + bool postedFirstImage : 1; + bool postedOnlyImage : 1; bool embedImages : 1; bool saveCompletePage : 1; bool preview : 1; diff --git a/plugins/FeedReader/lang/FeedReader_en.ts b/plugins/FeedReader/lang/FeedReader_en.ts index 89cde2fe0..f366ccc9c 100644 --- a/plugins/FeedReader/lang/FeedReader_en.ts +++ b/plugins/FeedReader/lang/FeedReader_en.ts @@ -9,7 +9,27 @@ - + + Board + + + + + Update board information + + + + + Only image + + + + + Use first image as board image + + + + Authentication (not yet supported) @@ -99,22 +119,22 @@ - + Type - + Forum - + Local Feed - + Transformation @@ -144,12 +164,12 @@ - + Update forum information - + Save complete web page (experimental for local feeds) @@ -164,18 +184,18 @@ - + Name: - + Feed Details - - + + Edit feed @@ -277,7 +297,7 @@ FeedReaderDialog - + Feeds @@ -402,7 +422,7 @@ FeedReaderFeedItem - + Expand @@ -542,12 +562,22 @@ - + The messages will be added to the forum - + + The messages will be added to the forum and the board + + + + + The messages will be added to the board + + + + No name @@ -659,12 +689,12 @@ - + Unknown - + Internal download error @@ -699,12 +729,7 @@ - - Can't create forum - - - - + Forum not found @@ -718,6 +743,21 @@ Forum has no author + + + Board not found + + + + + You are not admin of the board + + + + + Board has no author + + Can't read html @@ -790,7 +830,7 @@ - + Name: @@ -825,7 +865,7 @@ - + Title: diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index d70591c36..4c2eacaaf 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -24,6 +24,7 @@ #include "rsitems/rsconfigitems.h" #include "retroshare/rsiface.h" #include "retroshare/rsgxsforums.h" +#include "retroshare/rsposted.h" #include "util/rsstring.h" #include "util/rstime.h" #include "gxs/rsgenexchange.h" @@ -34,6 +35,7 @@ RsFeedReader *rsFeedReader = NULL; #define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour #define FEEDREADER_FORUM_PREFIX "RSS: " +#define FEEDREADER_POSTED_PREFIX "RSS: " #define MAX_REQUEST_AGE 30 // 30 seconds @@ -41,7 +43,7 @@ RsFeedReader *rsFeedReader = NULL; * #define FEEDREADER_DEBUG *********/ -p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums) +p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums, RsPosted *posted) : RsPQIService(RS_SERVICE_TYPE_PLUGIN_FEEDREADER, 5, pgHandler), mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mPreviewMutex("p3FeedReaderPreview") { @@ -55,6 +57,7 @@ p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums) mStandardProxyPort = 0; mLastClean = 0; mForums = forums; + mPosted = posted; mNotify = NULL; mSaveInBackground = false; mStopped = false; @@ -92,6 +95,7 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.updateInterval = feed->updateInterval; info.lastUpdate = feed->lastUpdate; info.forumId = feed->forumId; + info.postedId = feed->postedId; info.storageTime = feed->storageTime; info.errorState = feed->errorState; info.errorString = feed->errorString; @@ -110,6 +114,10 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.flag.deactivated = (feed->flag & RS_FEED_FLAG_DEACTIVATED); info.flag.forum = (feed->flag & RS_FEED_FLAG_FORUM); info.flag.updateForumInfo = (feed->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO); + info.flag.posted = (feed->flag & RS_FEED_FLAG_POSTED); + info.flag.updatePostedInfo = (feed->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO); + info.flag.postedFirstImage = (feed->flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE); + info.flag.postedOnlyImage = (feed->flag & RS_FEED_FLAG_POSTED_ONLY_IMAGE); info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES); info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE); @@ -151,6 +159,7 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed) feed->storageTime = info.storageTime; feed->forumId = info.forumId; + feed->postedId = info.postedId; feed->transformationType = info.transformationType; feed->xpathsToUse.ids = info.xpathsToUse; @@ -193,6 +202,21 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed) if (info.flag.updateForumInfo) { feed->flag |= RS_FEED_FLAG_UPDATE_FORUM_INFO; } + if (info.flag.posted) { + feed->flag |= RS_FEED_FLAG_POSTED; + } + if (info.flag.updatePostedInfo) { + feed->flag |= RS_FEED_FLAG_UPDATE_POSTED_INFO; + } + if (info.flag.updatePostedInfo) { + feed->flag |= RS_FEED_FLAG_UPDATE_POSTED_INFO; + } + if (info.flag.postedFirstImage) { + feed->flag |= RS_FEED_FLAG_POSTED_FIRST_IMAGE; + } + if (info.flag.postedOnlyImage) { + feed->flag |= RS_FEED_FLAG_POSTED_ONLY_IMAGE; + } } static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info) @@ -478,6 +502,9 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) std::string forumId; std::string forumName; std::string forumDescription; + std::string postedId; + std::string postedName; + std::string postedDescription; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -521,6 +548,7 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) RsFeedReaderFeed *fi = feedIt->second; std::string oldForumId = fi->forumId; + std::string oldPostedId = fi->postedId; std::string oldName = fi->name; std::string oldDescription = fi->description; @@ -534,6 +562,15 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) forumDescription = fi->description; forumName.insert(0, FEEDREADER_FORUM_PREFIX); } + + if ((fi->flag & RS_FEED_FLAG_POSTED) && (fi->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO) && !fi->postedId.empty() && + (fi->postedId != oldPostedId || fi->name != oldName || fi->description != oldDescription)) { + /* name or description changed, update posted */ + postedId = fi->postedId; + postedName = fi->name; + postedDescription = fi->description; + postedName.insert(0, FEEDREADER_POSTED_PREFIX); + } } IndicateConfigChanged(); @@ -550,6 +587,14 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) //TODO: error } + if (!postedId.empty()) { + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(postedId), postedGroup)) { + updatePostedGroup(postedGroup, postedName, postedDescription); + } + //TODO: error + } + return RS_FEED_ADD_RESULT_SUCCESS; } @@ -682,6 +727,7 @@ bool p3FeedReader::addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) fi->updateInterval = 0; fi->lastUpdate = 0; fi->forumId.clear(); + fi->postedId.clear(); fi->storageTime = 0; mFeeds[fi->feedId] = fi; @@ -1885,8 +1931,12 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list addedMsgs; std::string forumId; - RsGxsId authorId; + RsGxsId forumAuthorId; std::list forumMsgs; + std::string postedId; + RsGxsId postedAuthorId; + std::list postedMsgs; + uint32_t feedFlag = 0; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1903,7 +1953,9 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listsecond; bool forum = (fi->flag & RS_FEED_FLAG_FORUM) && !fi->preview; + bool posted = (fi->flag & RS_FEED_FLAG_POSTED) && !fi->preview; RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK; + feedFlag = fi->flag; if (forum && !msgs.empty()) { if (mForums) { @@ -1913,9 +1965,9 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listforumId), forumGroup)) { if (IS_GROUP_PUBLISHER(forumGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(forumGroup.mMeta.mSubscribeFlags)) { forumId = fi->forumId; - authorId = forumGroup.mMeta.mAuthorId; + forumAuthorId = forumGroup.mMeta.mAuthorId; - if (authorId.isNull()) { + if (forumAuthorId.isNull()) { errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR; } } else { @@ -1933,6 +1985,34 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listpostedId.empty()) { + /* check posted */ + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(fi->postedId), postedGroup)) { + if (IS_GROUP_PUBLISHER(postedGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(postedGroup.mMeta.mSubscribeFlags)) { + postedId = fi->postedId; + postedAuthorId = postedGroup.mMeta.mAuthorId; + + if (postedAuthorId.isNull()) { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR; + } + } else { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN; + } + } else { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - posted id is empty (" << fi->name << ")" << std::endl; + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not set" << std::endl; + } + } + /* process msgs */ if (errorState == RS_FEED_ERRORSTATE_OK) { /* process msgs */ @@ -1949,9 +2029,14 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listmsgId, "%lu", mNextMsgId++); } - if (forum) { + if (forum || posted) { miNew->flag = RS_FEEDMSG_FLAG_DELETED; - forumMsgs.push_back(*miNew); + if (forum) { + forumMsgs.push_back(*miNew); + } + if (posted) { + postedMsgs.push_back(*miNew); + } miNew->description.clear(); miNew->descriptionTransformed.clear(); } else { @@ -1996,7 +2081,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listcreateMsg(token, forumMsg) && waitForToken(token)) { + if (mForums->createMsg(token, forumMsg) && waitForToken(mForums, token)) { RsGxsGrpMsgIdPair msgPair; if (mForums->acknowledgeMsg(token, msgPair)) { /* set to new */ @@ -2026,6 +2111,67 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list(mPosted); + if (genExchange) { + /* add messages as posted messages */ + std::list::iterator msgIt; + for (msgIt = postedMsgs.begin(); msgIt != postedMsgs.end(); ++msgIt) { + RsFeedReaderMsg &mi = *msgIt; + + /* convert to posted messages */ + RsPostedPost postedPost; + postedPost.mMeta.mGroupId = RsGxsGroupId(postedId); + postedPost.mMeta.mMsgName = mi.title; + postedPost.mMeta.mAuthorId = postedAuthorId; + postedPost.mLink = mi.link; + + std::string description; + if (feedFlag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) { + if (!mi.postedFirstImage.empty()) { + /* use first image as image for posted and description without image as notes */ + postedPost.mImage.copy(mi.postedFirstImage.data(), mi.postedFirstImage.size()); + if (feedFlag & RS_FEED_FLAG_POSTED_ONLY_IMAGE) { + /* ignore description */ + } else { + description = mi.postedDescriptionWithoutFirstImage; + } + } else { + if (feedFlag & RS_FEED_FLAG_POSTED_ONLY_IMAGE) { + /* ignore messages without image */ + continue; + } + description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; + } + } else { + description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; + } + + postedPost.mNotes = description; + + uint32_t token; + if (mPosted->createPost(token, postedPost) && waitForToken(mPosted, token)) { + RsGxsGrpMsgIdPair msgPair; + if (mPosted->acknowledgeMsg(token, msgPair)) { + /* set to new */ + genExchange->setMsgStatusFlags(token, msgPair, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD); + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't add posted message " << mi.title << " for feed " << postedId << std::endl; +#endif + } + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not derived from RsGenExchange" << std::endl; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not set" << std::endl; + } + } + if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -2080,6 +2226,9 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s std::string forumId; std::string forumName; std::string forumDescription; + std::string postedId; + std::string postedName; + std::string postedDescription; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -2118,6 +2267,14 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s forumDescription = fi->description; forumName.insert(0, FEEDREADER_FORUM_PREFIX); } + + if ((fi->flag & RS_FEED_FLAG_POSTED) && (fi->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO) && !fi->postedId.empty() && !preview) { + /* change posted too */ + postedId = fi->postedId; + postedName = fi->name; + postedDescription = fi->description; + postedName.insert(0, FEEDREADER_POSTED_PREFIX); + } } if (changed) { @@ -2137,6 +2294,14 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s } //TODO: error } + + if (!postedId.empty()) { + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(postedId), postedGroup)) { + updatePostedGroup(postedGroup, postedName, postedDescription); + } + //TODO: error + } } bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup) @@ -2159,7 +2324,7 @@ bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &f uint32_t token; mForums->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); - if (!waitForToken(token)) { + if (!waitForToken(mForums, token)) { std::cerr << "p3FeedReader::getForumGroup - waitForToken for request failed" << std::endl; return false; } @@ -2202,7 +2367,7 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std return false; } - if (!waitForToken(token)) { + if (!waitForToken(mForums, token)) { std::cerr << "p3FeedReader::updateForumGroup - waitForToken for update failed" << std::endl; return false; } @@ -2211,13 +2376,85 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std return true; } -bool p3FeedReader::waitForToken(uint32_t token) +bool p3FeedReader::getPostedGroup(const RsGxsGroupId &groupId, RsPostedGroup &postedGroup) { - if (!mForums) { + if (!mPosted) { + std::cerr << "p3FeedReader::getPostedGroup - can't get posted group " << groupId.toStdString() << ", member mPosted is not set" << std::endl; return false; } - RsTokenService *service = mForums->getTokenService(); + if (groupId.isNull()) { + std::cerr << "p3FeedReader::getPostedGroup - group id is not valid" << std::endl; + return false; + } + + std::list grpIds; + grpIds.push_back(groupId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mPosted->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::getPostedGroup - waitForToken for request failed" << std::endl; + return false; + } + + std::vector groups; + if (!mPosted->getGroupData(token, groups)) { + std::cerr << "p3FeedReader::getPostedGroup - Error getting data" << std::endl; + return false; + } + + if (groups.size() != 1) { + std::cerr << "p3FeedReader::getPostedGroup - Wrong number of items" << std::endl; + return false; + } + + postedGroup = groups[0]; + + return true; +} + +bool p3FeedReader::updatePostedGroup(const RsPostedGroup &postedGroup, const std::string &groupName, const std::string &groupDescription) +{ + if (!mPosted) { + std::cerr << "p3FeedReader::updatePostedGroup - can't change posted " << postedGroup.mMeta.mGroupId.toStdString() << ", member mPosted is not set" << std::endl; + return false; + } + + if (postedGroup.mMeta.mGroupName == groupName && postedGroup.mDescription == groupDescription) { + /* No change */ + return true; + } + + RsPostedGroup newPostedGroup = postedGroup; + newPostedGroup.mMeta.mGroupName = groupName; + newPostedGroup.mDescription = groupDescription; + + uint32_t token; + if (!mPosted->updateGroup(token, newPostedGroup)) { + std::cerr << "p3FeedReader::updatePostedGroup - can't change posted " << newPostedGroup.mMeta.mGroupId.toStdString() << std::endl; + return false; + } + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::updatePostedGroup - waitForToken for update failed" << std::endl; + return false; + } + + /* Posted updated */ + return true; +} + +bool p3FeedReader::waitForToken(RsGxsIfaceHelper *interface, uint32_t token) +{ + if (!interface) { + return false; + } + + RsTokenService *service = interface->getTokenService(); int count = MAX_REQUEST_AGE * 2; while (!mStopped) { diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index 08fa3619b..d60b63ca2 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -33,11 +33,14 @@ class p3FeedReaderThread; class RsGxsForums; struct RsGxsForumGroup; +class RsPosted; +struct RsPostedGroup; +class RsGxsIfaceHelper; class p3FeedReader : public RsPQIService, public RsFeedReader { public: - p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums); + p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums, RsPosted *posted); /****************** FeedReader Interface *************/ virtual void stop(); @@ -92,7 +95,9 @@ public: bool getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup); bool updateForumGroup(const RsGxsForumGroup &forumGroup, const std::string &groupName, const std::string &groupDescription); - bool waitForToken(uint32_t token); + bool getPostedGroup(const RsGxsGroupId &groupId, RsPostedGroup &postedGroup); + bool updatePostedGroup(const RsPostedGroup &postedGroup, const std::string &groupName, const std::string &groupDescription); + bool waitForToken(RsGxsIfaceHelper *interface, uint32_t token); protected: /****************** p3Config STUFF *******************/ @@ -109,6 +114,7 @@ private: private: time_t mLastClean; RsGxsForums *mForums; + RsPosted *mPosted; RsFeedReaderNotify *mNotify; volatile bool mStopped; diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index 130d2fac1..00da7a007 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -1076,12 +1076,15 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe if (isRunning()) { /* process description */ + bool processPostedFirstImage = (feed.flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) ? TRUE : FALSE; + //long todo; // encoding HTMLWrapper html; if (html.readHTML(msg->description.c_str(), url.c_str())) { xmlNodePtr root = html.getRootElement(); if (root) { std::list nodesToDelete; + xmlNodePtr postedFirstImageNode = NULL; /* process all children */ std::list nodes; @@ -1212,6 +1215,12 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); if (html.setAttr(node, "src", imageBase64.c_str())) { removeImage = false; + + if (processPostedFirstImage && postedFirstImageNode == NULL) { + /* set first image */ + msg->postedFirstImage = data; + postedFirstImageNode = node; + } } } } @@ -1247,7 +1256,22 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe if (result == RS_FEED_ERRORSTATE_OK) { if (isRunning()) { - if (!html.saveHTML(msg->description)) { + if (html.saveHTML(msg->description)) { + if (postedFirstImageNode) { + /* Remove first image and create description without the image */ + xmlUnlinkNode(postedFirstImageNode); + xmlFreeNode(postedFirstImageNode); + + if (!html.saveHTML(msg->postedDescriptionWithoutFirstImage)) { + errorString = html.lastError(); +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; + std::cerr << " Error: " << errorString << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + } + } + } else { errorString = html.lastError(); #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; diff --git a/plugins/FeedReader/services/rsFeedReaderItems.cc b/plugins/FeedReader/services/rsFeedReaderItems.cc index 04a6c8f1e..5a2ad4fe1 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.cc +++ b/plugins/FeedReader/services/rsFeedReaderItems.cc @@ -46,6 +46,7 @@ void RsFeedReaderFeed::clear() storageTime = 0; flag = 0; forumId.clear(); + postedId.clear(); description.clear(); icon.clear(); errorState = RS_FEED_ERRORSTATE_OK; @@ -85,6 +86,7 @@ uint32_t RsFeedReaderSerialiser::sizeFeed(RsFeedReaderFeed *item) s += item->xpathsToUse.TlvSize(); s += item->xpathsToRemove.TlvSize(); s += GetTlvStringSize(item->xslt); + s += GetTlvStringSize(item->postedId); return s; } @@ -108,7 +110,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u offset += 8; /* add values */ - ok &= setRawUInt16(data, tlvsize, &offset, 2); /* version */ + ok &= setRawUInt16(data, tlvsize, &offset, 3); /* version */ ok &= setRawUInt32(data, tlvsize, &offset, item->feedId); ok &= setRawUInt32(data, tlvsize, &offset, item->parentId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, item->url); @@ -124,6 +126,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u ok &= setRawUInt32(data, tlvsize, &offset, item->storageTime); ok &= setRawUInt32(data, tlvsize, &offset, item->flag); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->postedId); ok &= setRawUInt32(data, tlvsize, &offset, item->errorState); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->errorString); ok &= setRawUInt32(data, tlvsize, &offset, item->transformationType); @@ -208,6 +211,9 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * ok &= getRawUInt32(data, rssize, &offset, &(item->storageTime)); ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + if (version >= 3) { + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->postedId); + } uint32_t errorState = 0; ok &= getRawUInt32(data, rssize, &offset, &errorState); item->errorState = (RsFeedReaderErrorState) errorState; diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index d2ee7574e..39d604f46 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -34,17 +34,21 @@ const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; /**************************************************************************/ -#define RS_FEED_FLAG_FOLDER 0x001 -#define RS_FEED_FLAG_INFO_FROM_FEED 0x002 -#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x004 -#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x008 -#define RS_FEED_FLAG_STANDARD_PROXY 0x010 -#define RS_FEED_FLAG_AUTHENTICATION 0x020 -#define RS_FEED_FLAG_DEACTIVATED 0x040 -#define RS_FEED_FLAG_FORUM 0x080 -#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x100 -#define RS_FEED_FLAG_EMBED_IMAGES 0x200 -#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x400 +#define RS_FEED_FLAG_FOLDER 0x0001 +#define RS_FEED_FLAG_INFO_FROM_FEED 0x0002 +#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x0004 +#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x0008 +#define RS_FEED_FLAG_STANDARD_PROXY 0x0010 +#define RS_FEED_FLAG_AUTHENTICATION 0x0020 +#define RS_FEED_FLAG_DEACTIVATED 0x0040 +#define RS_FEED_FLAG_FORUM 0x0080 +#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x0100 +#define RS_FEED_FLAG_EMBED_IMAGES 0x0200 +#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x0400 +#define RS_FEED_FLAG_POSTED 0x0800 +#define RS_FEED_FLAG_UPDATE_POSTED_INFO 0x1000 +#define RS_FEED_FLAG_POSTED_FIRST_IMAGE 0x2000 +#define RS_FEED_FLAG_POSTED_ONLY_IMAGE 0x4000 class RsFeedReaderFeed : public RsItem { @@ -76,6 +80,7 @@ public: time_t lastUpdate; uint32_t flag; // RS_FEED_FLAG_... std::string forumId; + std::string postedId; uint32_t storageTime; std::string description; std::string icon; @@ -118,6 +123,10 @@ public: std::string descriptionTransformed; time_t pubDate; uint32_t flag; // RS_FEEDMSG_FLAG_... + + // Only in memory when receiving messages + std::vector postedFirstImage; + std::string postedDescriptionWithoutFirstImage; }; class RsFeedReaderSerialiser: public RsSerialType