2018-11-04 09:48:33 -05:00
/*******************************************************************************
* plugins / FeedReader / services / p3FeedReader . cc *
* *
* Copyright ( C ) 2012 by Thunder < retroshare . project @ gmail . com > *
* *
* This program is free software : you can redistribute it and / or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation , either version 3 of the *
* License , or ( at your option ) any later version . *
* *
* This program 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 Affero General Public License for more details . *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program . If not , see < https : //www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-08-02 09:17:53 -04:00
2012-08-03 21:15:40 -04:00
# include "rsFeedReaderItems.h"
2012-08-02 09:17:53 -04:00
# include "p3FeedReader.h"
# include "p3FeedReaderThread.h"
2017-05-02 16:05:54 -04:00
# include "rsitems/rsconfigitems.h"
2012-08-02 09:17:53 -04:00
# include "retroshare/rsiface.h"
2014-11-24 17:40:29 -05:00
# include "retroshare/rsgxsforums.h"
2023-04-10 18:36:41 -04:00
# include "retroshare/rsposted.h"
2012-08-02 09:17:53 -04:00
# include "util/rsstring.h"
2018-01-27 14:22:31 -05:00
# include "util/rstime.h"
2014-11-24 17:40:29 -05:00
# include "gxs/rsgenexchange.h"
# include <unistd.h>
2012-08-02 09:17:53 -04:00
RsFeedReader * rsFeedReader = NULL ;
# define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour
2014-11-24 17:40:29 -05:00
# define FEEDREADER_FORUM_PREFIX "RSS: "
2023-04-10 18:36:41 -04:00
# define FEEDREADER_POSTED_PREFIX "RSS: "
2014-11-24 17:40:29 -05:00
# define MAX_REQUEST_AGE 30 // 30 seconds
2012-08-02 09:17:53 -04:00
/*********
* # define FEEDREADER_DEBUG
* * * * * * * * */
2023-04-10 18:36:41 -04:00
p3FeedReader : : p3FeedReader ( RsPluginHandler * pgHandler , RsGxsForums * forums , RsPosted * posted )
2014-04-23 16:48:02 -04:00
: RsPQIService ( RS_SERVICE_TYPE_PLUGIN_FEEDREADER , 5 , pgHandler ) ,
2012-08-13 17:35:11 -04:00
mFeedReaderMtx ( " p3FeedReader " ) , mDownloadMutex ( " p3FeedReaderDownload " ) , mProcessMutex ( " p3FeedReaderProcess " ) , mPreviewMutex ( " p3FeedReaderPreview " )
2012-08-02 09:17:53 -04:00
{
mNextFeedId = 1 ;
mNextMsgId = 1 ;
2012-08-13 17:35:11 -04:00
mNextPreviewFeedId = - 1 ; // use negative values
mNextPreviewMsgId = - 1 ; // use negative values
2012-08-02 09:17:53 -04:00
mStandardUpdateInterval = 60 * 60 ; // 60 minutes
mStandardStorageTime = 30 * 60 * 60 * 24 ; // 30 days
mStandardUseProxy = false ;
mStandardProxyPort = 0 ;
mLastClean = 0 ;
2014-01-03 10:05:48 -05:00
mForums = forums ;
2023-04-10 18:36:41 -04:00
mPosted = posted ;
2012-08-02 09:17:53 -04:00
mNotify = NULL ;
2013-05-01 17:16:46 -04:00
mSaveInBackground = false ;
2014-11-24 17:40:29 -05:00
mStopped = false ;
2012-08-02 09:17:53 -04:00
2012-08-13 17:35:11 -04:00
mPreviewDownloadThread = NULL ;
mPreviewProcessThread = NULL ;
2012-08-02 09:17:53 -04:00
/* start download thread */
2020-11-08 07:22:59 -05:00
p3FeedReaderThread * frt = new p3FeedReaderThread ( this , p3FeedReaderThread : : DOWNLOAD , 0 ) ;
2012-08-02 09:17:53 -04:00
mThreads . push_back ( frt ) ;
2016-06-01 10:58:56 -04:00
frt - > start ( " fr download " ) ;
2012-08-02 09:17:53 -04:00
/* start process thread */
2020-11-08 07:22:59 -05:00
frt = new p3FeedReaderThread ( this , p3FeedReaderThread : : PROCESS , 0 ) ;
2012-08-02 09:17:53 -04:00
mThreads . push_back ( frt ) ;
2016-06-01 10:58:56 -04:00
frt - > start ( " fr process " ) ;
2012-08-02 09:17:53 -04:00
}
/***************************************************************************/
/****************************** RsFeedReader *******************************/
/***************************************************************************/
static void feedToInfo ( const RsFeedReaderFeed * feed , FeedInfo & info )
{
info . feedId = feed - > feedId ;
info . parentId = feed - > parentId ;
info . url = feed - > url ;
info . name = feed - > name ;
info . description = feed - > description ;
info . icon = feed - > icon ;
info . user = feed - > user ;
info . password = feed - > password ;
info . proxyAddress = feed - > proxyAddress ;
info . proxyPort = feed - > proxyPort ;
info . updateInterval = feed - > updateInterval ;
info . lastUpdate = feed - > lastUpdate ;
info . forumId = feed - > forumId ;
2023-04-10 18:36:41 -04:00
info . postedId = feed - > postedId ;
2012-08-02 09:17:53 -04:00
info . storageTime = feed - > storageTime ;
2012-08-13 17:35:11 -04:00
info . errorState = feed - > errorState ;
2012-08-02 09:17:53 -04:00
info . errorString = feed - > errorString ;
2013-01-21 19:11:43 -05:00
info . transformationType = feed - > transformationType ;
2012-09-04 19:53:04 -04:00
info . xpathsToUse = feed - > xpathsToUse . ids ;
info . xpathsToRemove = feed - > xpathsToRemove . ids ;
2013-01-21 19:11:43 -05:00
info . xslt = feed - > xslt ;
2012-09-04 19:53:04 -04:00
2012-08-02 09:17:53 -04:00
info . flag . folder = ( feed - > flag & RS_FEED_FLAG_FOLDER ) ;
info . flag . infoFromFeed = ( feed - > flag & RS_FEED_FLAG_INFO_FROM_FEED ) ;
info . flag . standardStorageTime = ( feed - > flag & RS_FEED_FLAG_STANDARD_STORAGE_TIME ) ;
info . flag . standardUpdateInterval = ( feed - > flag & RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL ) ;
info . flag . standardProxy = ( feed - > flag & RS_FEED_FLAG_STANDARD_PROXY ) ;
info . flag . authentication = ( feed - > flag & RS_FEED_FLAG_AUTHENTICATION ) ;
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 ) ;
2023-04-10 18:36:41 -04:00
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 ) ;
2012-08-10 14:06:29 -04:00
info . flag . embedImages = ( feed - > flag & RS_FEED_FLAG_EMBED_IMAGES ) ;
info . flag . saveCompletePage = ( feed - > flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE ) ;
2012-08-02 09:17:53 -04:00
2012-08-13 17:35:11 -04:00
info . flag . preview = feed - > preview ;
2012-08-02 09:17:53 -04:00
switch ( feed - > workstate ) {
case RsFeedReaderFeed : : WAITING :
info . workstate = FeedInfo : : WAITING ;
break ;
case RsFeedReaderFeed : : WAITING_TO_DOWNLOAD :
info . workstate = FeedInfo : : WAITING_TO_DOWNLOAD ;
break ;
case RsFeedReaderFeed : : DOWNLOADING :
info . workstate = FeedInfo : : DOWNLOADING ;
break ;
case RsFeedReaderFeed : : WAITING_TO_PROCESS :
info . workstate = FeedInfo : : WAITING_TO_PROCESS ;
break ;
case RsFeedReaderFeed : : PROCESSING :
info . workstate = FeedInfo : : PROCESSING ;
break ;
}
}
2014-11-24 17:40:29 -05:00
static void infoToFeed ( const FeedInfo & info , RsFeedReaderFeed * feed )
2012-08-02 09:17:53 -04:00
{
// feed->feedId = info.feedId;
feed - > parentId = info . parentId ;
feed - > url = info . url ;
feed - > name = info . name ;
feed - > description = info . description ;
// feed->icon = info.icon;
feed - > user = info . user ;
feed - > password = info . password ;
feed - > proxyAddress = info . proxyAddress ;
feed - > proxyPort = info . proxyPort ;
feed - > updateInterval = info . updateInterval ;
// feed->lastUpdate = info.lastUpdate;
feed - > storageTime = info . storageTime ;
2014-11-24 17:40:29 -05:00
feed - > forumId = info . forumId ;
2023-04-10 18:36:41 -04:00
feed - > postedId = info . postedId ;
2012-08-02 09:17:53 -04:00
2013-01-21 19:11:43 -05:00
feed - > transformationType = info . transformationType ;
2012-09-04 19:53:04 -04:00
feed - > xpathsToUse . ids = info . xpathsToUse ;
feed - > xpathsToRemove . ids = info . xpathsToRemove ;
2013-01-21 19:11:43 -05:00
feed - > xslt = info . xslt ;
2012-09-04 19:53:04 -04:00
2012-08-13 17:35:11 -04:00
// feed->preview = info.flag.preview;
2012-08-02 09:17:53 -04:00
feed - > flag = 0 ;
if ( info . flag . infoFromFeed ) {
feed - > flag | = RS_FEED_FLAG_INFO_FROM_FEED ;
}
if ( info . flag . standardStorageTime ) {
feed - > flag | = RS_FEED_FLAG_STANDARD_STORAGE_TIME ;
}
if ( info . flag . standardUpdateInterval ) {
feed - > flag | = RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL ;
}
if ( info . flag . standardProxy ) {
feed - > flag | = RS_FEED_FLAG_STANDARD_PROXY ;
}
if ( info . flag . authentication ) {
feed - > flag | = RS_FEED_FLAG_AUTHENTICATION ;
}
if ( info . flag . deactivated ) {
feed - > flag | = RS_FEED_FLAG_DEACTIVATED ;
}
2012-08-10 14:06:29 -04:00
if ( info . flag . embedImages ) {
feed - > flag | = RS_FEED_FLAG_EMBED_IMAGES ;
}
if ( info . flag . saveCompletePage ) {
feed - > flag | = RS_FEED_FLAG_SAVE_COMPLETE_PAGE ;
}
2014-11-24 17:40:29 -05:00
if ( info . flag . folder ) {
feed - > flag | = RS_FEED_FLAG_FOLDER ;
}
if ( info . flag . forum ) {
feed - > flag | = RS_FEED_FLAG_FORUM ;
2012-08-02 09:17:53 -04:00
}
if ( info . flag . updateForumInfo ) {
feed - > flag | = RS_FEED_FLAG_UPDATE_FORUM_INFO ;
}
2023-04-10 18:36:41 -04:00
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 ;
}
2012-08-02 09:17:53 -04:00
}
static void feedMsgToInfo ( const RsFeedReaderMsg * msg , FeedMsgInfo & info )
{
info . msgId = msg - > msgId ;
info . feedId = msg - > feedId ;
info . title = msg - > title ;
info . link = msg - > link ;
info . author = msg - > author ;
info . description = msg - > description ;
2013-01-21 19:11:43 -05:00
info . descriptionTransformed = msg - > descriptionTransformed ;
2012-08-02 09:17:53 -04:00
info . pubDate = msg - > pubDate ;
info . flag . isnew = ( msg - > flag & RS_FEEDMSG_FLAG_NEW ) ;
info . flag . read = ( msg - > flag & RS_FEEDMSG_FLAG_READ ) ;
2013-01-14 17:41:31 -05:00
info . flag . deleted = ( msg - > flag & RS_FEEDMSG_FLAG_DELETED ) ;
2012-08-02 09:17:53 -04:00
}
void p3FeedReader : : setNotify ( RsFeedReaderNotify * notify )
{
mNotify = notify ;
}
uint32_t p3FeedReader : : getStandardStorageTime ( )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
return mStandardStorageTime ;
}
2014-04-23 16:48:02 -04:00
RsServiceInfo p3FeedReader : : getServiceInfo ( )
{
const std : : string FEEDREADER_APP_NAME = " FEEDREADER " ;
const uint16_t FEEDREADER_APP_MAJOR_VERSION = 1 ;
const uint16_t FEEDREADER_APP_MINOR_VERSION = 0 ;
const uint16_t FEEDREADER_MIN_MAJOR_VERSION = 1 ;
const uint16_t FEEDREADER_MIN_MINOR_VERSION = 0 ;
return RsServiceInfo ( RS_SERVICE_TYPE_PLUGIN_FEEDREADER ,
FEEDREADER_APP_NAME ,
FEEDREADER_APP_MAJOR_VERSION ,
FEEDREADER_APP_MINOR_VERSION ,
FEEDREADER_MIN_MAJOR_VERSION ,
FEEDREADER_MIN_MINOR_VERSION ) ;
}
2012-08-02 09:17:53 -04:00
void p3FeedReader : : setStandardStorageTime ( uint32_t storageTime )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
if ( mStandardStorageTime ! = storageTime ) {
mStandardStorageTime = storageTime ;
IndicateConfigChanged ( ) ;
}
}
uint32_t p3FeedReader : : getStandardUpdateInterval ( )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
return mStandardUpdateInterval ;
}
void p3FeedReader : : setStandardUpdateInterval ( uint32_t updateInterval )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
if ( mStandardUpdateInterval ! = updateInterval ) {
mStandardUpdateInterval = updateInterval ;
IndicateConfigChanged ( ) ;
}
}
bool p3FeedReader : : getStandardProxy ( std : : string & proxyAddress , uint16_t & proxyPort )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
proxyAddress = mStandardProxyAddress ;
proxyPort = mStandardProxyPort ;
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
return mStandardUseProxy ;
}
void p3FeedReader : : setStandardProxy ( bool useProxy , const std : : string & proxyAddress , uint16_t proxyPort )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
if ( useProxy ! = mStandardUseProxy | | proxyAddress ! = mStandardProxyAddress | | proxyPort ! = mStandardProxyPort ) {
mStandardProxyAddress = proxyAddress ;
mStandardProxyPort = proxyPort ;
mStandardUseProxy = useProxy ;
IndicateConfigChanged ( ) ;
}
}
2013-05-01 17:16:46 -04:00
bool p3FeedReader : : getSaveInBackground ( )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
return mSaveInBackground ;
}
void p3FeedReader : : setSaveInBackground ( bool saveInBackground )
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
if ( saveInBackground ! = mSaveInBackground ) {
mSaveInBackground = saveInBackground ;
IndicateConfigChanged ( ) ;
}
}
2012-08-02 09:17:53 -04:00
void p3FeedReader : : stop ( )
{
2014-11-24 17:40:29 -05:00
mStopped = true ;
2012-08-13 17:35:11 -04:00
{
RsStackMutex stack ( mPreviewMutex ) ; /******* LOCK STACK MUTEX *********/
stopPreviewThreads_locked ( ) ;
}
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* stop threads */
std : : list < p3FeedReaderThread * > : : iterator it ;
for ( it = mThreads . begin ( ) ; it ! = mThreads . end ( ) ; + + it ) {
2020-11-08 07:22:59 -05:00
( * it ) - > fullstop ( ) ;
2012-08-13 17:35:11 -04:00
delete ( * it ) ;
}
mThreads . clear ( ) ;
}
}
void p3FeedReader : : stopPreviewThreads_locked ( )
{
if ( mPreviewDownloadThread ) {
2020-11-08 07:22:59 -05:00
mPreviewDownloadThread - > fullstop ( ) ;
2012-08-13 17:35:11 -04:00
delete mPreviewDownloadThread ;
mPreviewDownloadThread = NULL ;
}
if ( mPreviewProcessThread ) {
2020-11-08 07:22:59 -05:00
mPreviewProcessThread - > fullstop ( ) ;
2012-08-13 17:35:11 -04:00
delete mPreviewProcessThread ;
mPreviewProcessThread = NULL ;
2012-08-02 09:17:53 -04:00
}
}
2020-11-08 07:22:59 -05:00
RsFeedAddResult p3FeedReader : : addFolder ( uint32_t parentId , const std : : string & name , uint32_t & feedId )
2012-08-02 09:17:53 -04:00
{
2020-11-08 07:22:59 -05:00
feedId = 0 ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
if ( parentId ) {
2012-08-02 09:17:53 -04:00
/* check parent id */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator parentIt = mFeeds . find ( parentId ) ;
2012-08-02 09:17:53 -04:00
if ( parentIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::addFolder - parent id " < < parentId < < " not found " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND ;
}
if ( ( parentIt - > second - > flag & RS_FEED_FLAG_FOLDER ) = = 0 ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::addFolder - parent " < < parentIt - > second - > name < < " is no folder " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER ;
}
}
RsFeedReaderFeed * fi = new RsFeedReaderFeed ;
2020-11-08 07:22:59 -05:00
fi - > feedId = mNextFeedId + + ;
2012-08-02 09:17:53 -04:00
fi - > parentId = parentId ;
fi - > name = name ;
fi - > flag = RS_FEED_FLAG_FOLDER ;
mFeeds [ fi - > feedId ] = fi ;
feedId = fi - > feedId ;
}
IndicateConfigChanged ( ) ;
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_ADD ) ;
2012-08-02 09:17:53 -04:00
}
return RS_FEED_ADD_RESULT_SUCCESS ;
}
2020-11-08 07:22:59 -05:00
RsFeedAddResult p3FeedReader : : setFolder ( uint32_t feedId , const std : : string & name )
2012-08-02 09:17:53 -04:00
{
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFolder - feed id " < < feedId < < " , name " < < name < < std : : endl ;
# endif
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFolder - feed id " < < feedId < < " not found " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_FEED_NOT_FOUND ;
}
if ( ( feedIt - > second - > flag & RS_FEED_FLAG_FOLDER ) = = 0 ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFolder - feed " < < feedIt - > second - > name < < " is no folder " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
if ( fi - > name = = name ) {
return RS_FEED_ADD_RESULT_SUCCESS ;
}
fi - > name = name ;
}
IndicateConfigChanged ( ) ;
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
return RS_FEED_ADD_RESULT_SUCCESS ;
}
2020-11-08 07:22:59 -05:00
RsFeedAddResult p3FeedReader : : addFeed ( const FeedInfo & feedInfo , uint32_t & feedId )
2012-08-02 09:17:53 -04:00
{
2020-11-08 07:22:59 -05:00
feedId = 0 ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::addFeed - add feed " < < feedInfo . name < < " , url " < < feedInfo . url < < std : : endl ;
# endif
2020-11-08 07:22:59 -05:00
if ( feedInfo . parentId ) {
2012-08-02 09:17:53 -04:00
/* check parent id */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator parentIt = mFeeds . find ( feedInfo . parentId ) ;
2012-08-02 09:17:53 -04:00
if ( parentIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::addFeed - parent id " < < feedInfo . parentId < < " not found " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND ;
}
if ( ( parentIt - > second - > flag & RS_FEED_FLAG_FOLDER ) = = 0 ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::addFeed - parent " < < parentIt - > second - > name < < " is no folder " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER ;
}
}
RsFeedReaderFeed * fi = new RsFeedReaderFeed ;
2014-11-24 17:40:29 -05:00
infoToFeed ( feedInfo , fi ) ;
2020-11-08 07:22:59 -05:00
fi - > feedId = mNextFeedId + + ;
2012-08-02 09:17:53 -04:00
mFeeds [ fi - > feedId ] = fi ;
feedId = fi - > feedId ;
}
IndicateConfigChanged ( ) ;
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_ADD ) ;
2012-08-02 09:17:53 -04:00
}
return RS_FEED_ADD_RESULT_SUCCESS ;
}
2020-11-08 07:22:59 -05:00
RsFeedAddResult p3FeedReader : : setFeed ( uint32_t feedId , const FeedInfo & feedInfo )
2012-08-02 09:17:53 -04:00
{
std : : string forumId ;
2014-11-24 17:40:29 -05:00
std : : string forumName ;
std : : string forumDescription ;
2023-04-10 18:36:41 -04:00
std : : string postedId ;
std : : string postedName ;
std : : string postedDescription ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeed - set feed " < < feedInfo . name < < " , url " < < feedInfo . url < < std : : endl ;
# endif
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeed - feed id " < < feedId < < " not found " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_FEED_NOT_FOUND ;
}
if ( feedIt - > second - > flag & RS_FEED_FLAG_FOLDER ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeed - feed " < < feedIt - > second - > name < < " is a folder " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_FEED_IS_FOLDER ;
}
2020-11-08 07:22:59 -05:00
if ( feedInfo . parentId ) {
2012-08-02 09:17:53 -04:00
/* check parent id */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator parentIt = mFeeds . find ( feedInfo . parentId ) ;
2012-08-02 09:17:53 -04:00
if ( parentIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeed - parent id " < < feedInfo . parentId < < " not found " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND ;
}
if ( ( parentIt - > second - > flag & RS_FEED_FLAG_FOLDER ) = = 0 ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeed - parent " < < parentIt - > second - > name < < " is no folder " < < std : : endl ;
# endif
return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER ;
}
}
RsFeedReaderFeed * fi = feedIt - > second ;
2014-11-24 17:40:29 -05:00
std : : string oldForumId = fi - > forumId ;
2023-04-10 18:36:41 -04:00
std : : string oldPostedId = fi - > postedId ;
2012-08-02 09:17:53 -04:00
std : : string oldName = fi - > name ;
std : : string oldDescription = fi - > description ;
2014-11-24 17:40:29 -05:00
infoToFeed ( feedInfo , fi ) ;
2012-08-02 09:17:53 -04:00
2014-11-24 17:40:29 -05:00
if ( ( fi - > flag & RS_FEED_FLAG_FORUM ) & & ( fi - > flag & RS_FEED_FLAG_UPDATE_FORUM_INFO ) & & ! fi - > forumId . empty ( ) & &
( fi - > forumId ! = oldForumId | | fi - > name ! = oldName | | fi - > description ! = oldDescription ) ) {
/* name or description changed, update forum */
forumId = fi - > forumId ;
forumName = fi - > name ;
forumDescription = fi - > description ;
forumName . insert ( 0 , FEEDREADER_FORUM_PREFIX ) ;
}
2023-04-10 18:36:41 -04:00
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 ) ;
}
2012-08-02 09:17:53 -04:00
}
IndicateConfigChanged ( ) ;
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
2014-11-24 17:40:29 -05:00
if ( ! forumId . empty ( ) ) {
RsGxsForumGroup forumGroup ;
if ( getForumGroup ( RsGxsGroupId ( forumId ) , forumGroup ) ) {
updateForumGroup ( forumGroup , forumName , forumDescription ) ;
}
//TODO: error
}
2012-08-02 09:17:53 -04:00
2023-04-10 18:36:41 -04:00
if ( ! postedId . empty ( ) ) {
RsPostedGroup postedGroup ;
if ( getPostedGroup ( RsGxsGroupId ( postedId ) , postedGroup ) ) {
updatePostedGroup ( postedGroup , postedName , postedDescription ) ;
}
//TODO: error
}
2012-08-02 09:17:53 -04:00
return RS_FEED_ADD_RESULT_SUCCESS ;
}
void p3FeedReader : : deleteAllMsgs_locked ( RsFeedReaderFeed * fi )
{
if ( ! fi ) {
return ;
}
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; + + msgIt ) {
2012-08-02 09:17:53 -04:00
delete ( msgIt - > second ) ;
}
2012-09-04 19:53:04 -04:00
fi - > msgs . clear ( ) ;
2012-08-02 09:17:53 -04:00
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : removeFeed ( uint32_t feedId )
2012-08-02 09:17:53 -04:00
{
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > removedFeedIds ;
2012-08-13 17:35:11 -04:00
bool changed = false ;
bool preview = false ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::removeFeed - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
removedFeedIds . push_back ( feedId ) ;
RsFeedReaderFeed * fi = feedIt - > second ;
mFeeds . erase ( feedIt ) ;
2012-08-13 17:35:11 -04:00
changed = ! fi - > preview ;
preview = fi - > preview ;
2012-08-02 09:17:53 -04:00
if ( fi - > flag & RS_FEED_FLAG_FOLDER ) {
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > feedIds ;
2012-08-02 09:17:53 -04:00
feedIds . push_back ( fi - > feedId ) ;
while ( ! feedIds . empty ( ) ) {
2020-11-08 07:22:59 -05:00
uint32_t parentId = feedIds . front ( ) ;
2012-08-02 09:17:53 -04:00
feedIds . pop_front ( ) ;
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt1 ;
2012-08-02 09:17:53 -04:00
for ( feedIt1 = mFeeds . begin ( ) ; feedIt1 ! = mFeeds . end ( ) ; ) {
RsFeedReaderFeed * fi1 = feedIt1 - > second ;
if ( fi1 - > parentId = = parentId ) {
removedFeedIds . push_back ( fi1 - > feedId ) ;
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator tempIt = feedIt1 ;
2012-08-02 09:17:53 -04:00
+ + feedIt1 ;
mFeeds . erase ( tempIt ) ;
if ( fi1 - > flag & RS_FEED_FLAG_FOLDER ) {
feedIds . push_back ( fi - > feedId ) ;
}
deleteAllMsgs_locked ( fi1 ) ;
delete ( fi1 ) ;
continue ;
}
+ + feedIt1 ;
}
}
}
deleteAllMsgs_locked ( fi ) ;
delete ( fi ) ;
}
2012-08-13 17:35:11 -04:00
if ( changed ) {
IndicateConfigChanged ( ) ;
}
if ( preview ) {
RsStackMutex stack ( mPreviewMutex ) ; /******* LOCK STACK MUTEX *********/
/* only check download thread */
if ( mPreviewDownloadThread & & mPreviewDownloadThread - > getFeedId ( ) = = feedId ) {
stopPreviewThreads_locked ( ) ;
}
}
2012-08-02 09:17:53 -04:00
if ( mNotify ) {
/* only notify remove of feed */
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > : : iterator it ;
2012-08-02 09:17:53 -04:00
for ( it = removedFeedIds . begin ( ) ; it ! = removedFeedIds . end ( ) ; + + it ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( * it , NOTIFY_TYPE_DEL ) ;
2012-08-02 09:17:53 -04:00
}
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : addPreviewFeed ( const FeedInfo & feedInfo , uint32_t & feedId )
2012-08-13 17:35:11 -04:00
{
{
RsStackMutex stack ( mPreviewMutex ) ; /******* LOCK STACK MUTEX *********/
stopPreviewThreads_locked ( ) ;
}
2020-11-08 07:22:59 -05:00
feedId = 0 ;
2012-08-13 17:35:11 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::addPreviewFeed - add feed " < < feedInfo . name < < " , url " < < feedInfo . url < < std : : endl ;
# endif
RsFeedReaderFeed * fi = new RsFeedReaderFeed ;
2014-11-24 17:40:29 -05:00
infoToFeed ( feedInfo , fi ) ;
2020-11-08 07:22:59 -05:00
fi - > feedId = mNextPreviewFeedId - - ;
2012-08-13 17:35:11 -04:00
fi - > preview = true ;
/* process feed */
fi - > workstate = RsFeedReaderFeed : : WAITING_TO_DOWNLOAD ;
fi - > content . clear ( ) ;
/* clear not needed members */
2020-11-08 07:22:59 -05:00
fi - > parentId = 0 ;
2012-08-13 17:35:11 -04:00
fi - > updateInterval = 0 ;
fi - > lastUpdate = 0 ;
fi - > forumId . clear ( ) ;
2023-04-10 18:36:41 -04:00
fi - > postedId . clear ( ) ;
2012-08-13 17:35:11 -04:00
fi - > storageTime = 0 ;
mFeeds [ fi - > feedId ] = fi ;
feedId = fi - > feedId ;
}
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_ADD ) ;
2012-08-13 17:35:11 -04:00
}
{
RsStackMutex stack ( mPreviewMutex ) ; /******* LOCK STACK MUTEX *********/
/* start download thread for preview */
mPreviewDownloadThread = new p3FeedReaderThread ( this , p3FeedReaderThread : : DOWNLOAD , feedId ) ;
2016-06-01 10:58:56 -04:00
mPreviewDownloadThread - > start ( " fr preview dl " ) ;
2012-08-13 17:35:11 -04:00
/* start process thread for preview */
mPreviewProcessThread = new p3FeedReaderThread ( this , p3FeedReaderThread : : PROCESS , feedId ) ;
2016-06-01 10:58:56 -04:00
mPreviewProcessThread - > start ( " fr preview proc " ) ;
2012-08-13 17:35:11 -04:00
}
return true ;
}
2020-11-08 07:22:59 -05:00
void p3FeedReader : : getFeedList ( uint32_t parentId , std : : list < FeedInfo > & feedInfos )
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt ;
2012-08-02 09:17:53 -04:00
for ( feedIt = mFeeds . begin ( ) ; feedIt ! = mFeeds . end ( ) ; + + feedIt ) {
RsFeedReaderFeed * fi = feedIt - > second ;
2012-08-13 17:35:11 -04:00
if ( fi - > preview ) {
continue ;
}
2012-08-02 09:17:53 -04:00
if ( fi - > parentId = = parentId ) {
FeedInfo feedInfo ;
feedToInfo ( fi , feedInfo ) ;
feedInfos . push_back ( feedInfo ) ;
}
}
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : getFeedInfo ( uint32_t feedId , FeedInfo & feedInfo )
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getFeedInfo - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
feedToInfo ( feedIt - > second , feedInfo ) ;
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : getMsgInfo ( uint32_t feedId , const std : : string & msgId , FeedMsgInfo & msgInfo )
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getMsgInfo - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
msgIt = fi - > msgs . find ( msgId ) ;
if ( msgIt = = fi - > msgs . end ( ) ) {
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getMsgInfo - msg " < < msgId < < " not found " < < std : : endl ;
# endif
return false ;
}
feedMsgToInfo ( msgIt - > second , msgInfo ) ;
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : removeMsg ( uint32_t feedId , const std : : string & msgId )
2012-08-02 09:17:53 -04:00
{
2012-08-13 17:35:11 -04:00
bool changed = false ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::removeMsg - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
2012-08-13 17:35:11 -04:00
changed = ! fi - > preview ;
2012-08-02 09:17:53 -04:00
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
msgIt = fi - > msgs . find ( msgId ) ;
if ( msgIt = = fi - > msgs . end ( ) ) {
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::removeMsg - msg " < < msgId < < " not found " < < std : : endl ;
# endif
return false ;
}
2013-01-21 19:11:43 -05:00
RsFeedReaderMsg * mi = msgIt - > second ;
mi - > flag | = RS_FEEDMSG_FLAG_DELETED | RS_FEEDMSG_FLAG_READ ;
mi - > flag & = ~ RS_FEEDMSG_FLAG_NEW ;
mi - > description . clear ( ) ;
mi - > descriptionTransformed . clear ( ) ;
2012-08-02 09:17:53 -04:00
}
2012-08-13 17:35:11 -04:00
if ( changed ) {
IndicateConfigChanged ( ) ;
}
2012-08-02 09:17:53 -04:00
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
mNotify - > notifyMsgChanged ( feedId , msgId , NOTIFY_TYPE_DEL ) ;
2012-08-02 09:17:53 -04:00
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : removeMsgs ( uint32_t feedId , const std : : list < std : : string > & msgIds )
2012-08-02 09:17:53 -04:00
{
std : : list < std : : string > removedMsgs ;
2012-08-13 17:35:11 -04:00
bool changed = false ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::removeMsgs - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
2012-08-13 17:35:11 -04:00
changed = ! fi - > preview ;
2012-08-02 09:17:53 -04:00
std : : list < std : : string > : : const_iterator idIt ;
for ( idIt = msgIds . begin ( ) ; idIt ! = msgIds . end ( ) ; + + idIt ) {
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
msgIt = fi - > msgs . find ( * idIt ) ;
if ( msgIt = = fi - > msgs . end ( ) ) {
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::removeMsgs - msg " < < * idIt < < " not found " < < std : : endl ;
# endif
continue ;
}
2013-01-21 19:11:43 -05:00
RsFeedReaderMsg * mi = msgIt - > second ;
mi - > flag | = RS_FEEDMSG_FLAG_DELETED | RS_FEEDMSG_FLAG_READ ;
mi - > flag & = ~ RS_FEEDMSG_FLAG_NEW ;
mi - > description . clear ( ) ;
mi - > descriptionTransformed . clear ( ) ;
2012-08-02 09:17:53 -04:00
removedMsgs . push_back ( * idIt ) ;
}
}
2012-08-13 17:35:11 -04:00
if ( changed ) {
IndicateConfigChanged ( ) ;
}
2012-08-02 09:17:53 -04:00
if ( mNotify & & ! removedMsgs . empty ( ) ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
std : : list < std : : string > : : iterator it ;
for ( it = removedMsgs . begin ( ) ; it ! = removedMsgs . end ( ) ; + + it ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyMsgChanged ( feedId , * it , NOTIFY_TYPE_DEL ) ;
2012-08-02 09:17:53 -04:00
}
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : getMessageCount ( uint32_t feedId , uint32_t * msgCount , uint32_t * newCount , uint32_t * unreadCount )
2012-08-02 09:17:53 -04:00
{
if ( msgCount ) * msgCount = 0 ;
if ( unreadCount ) * unreadCount = 0 ;
if ( newCount ) * newCount = 0 ;
if ( ! msgCount & & ! unreadCount & & ! newCount ) {
return true ;
}
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
if ( feedId = = 0 ) {
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt ;
2012-12-20 08:30:16 -05:00
for ( feedIt = mFeeds . begin ( ) ; feedIt ! = mFeeds . end ( ) ; + + feedIt ) {
RsFeedReaderFeed * fi = feedIt - > second ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; + + msgIt ) {
RsFeedReaderMsg * mi = msgIt - > second ;
if ( mi - > flag & RS_FEEDMSG_FLAG_DELETED ) {
continue ;
}
if ( msgCount ) + + ( * msgCount ) ;
if ( newCount & & ( mi - > flag & RS_FEEDMSG_FLAG_NEW ) ) + + ( * newCount ) ;
if ( unreadCount & & ( mi - > flag & RS_FEEDMSG_FLAG_READ ) = = 0 ) + + ( * unreadCount ) ;
}
}
} else {
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-12-20 08:30:16 -05:00
if ( feedIt = = mFeeds . end ( ) ) {
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
2012-12-20 08:30:16 -05:00
std : : cerr < < " p3FeedReader::getMessageCount - feed " < < feedId < < " not found " < < std : : endl ;
2012-08-02 09:17:53 -04:00
# endif
2012-12-20 08:30:16 -05:00
return false ;
}
2012-08-02 09:17:53 -04:00
2012-12-20 08:30:16 -05:00
RsFeedReaderFeed * fi = feedIt - > second ;
2012-08-02 09:17:53 -04:00
2012-12-20 08:30:16 -05:00
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; + + msgIt ) {
RsFeedReaderMsg * mi = msgIt - > second ;
2012-08-02 09:17:53 -04:00
2012-12-20 08:30:16 -05:00
if ( mi - > flag & RS_FEEDMSG_FLAG_DELETED ) {
continue ;
}
2012-08-02 09:17:53 -04:00
2012-12-20 08:30:16 -05:00
if ( msgCount ) + + ( * msgCount ) ;
if ( newCount & & ( mi - > flag & RS_FEEDMSG_FLAG_NEW ) ) + + ( * newCount ) ;
if ( unreadCount & & ( mi - > flag & RS_FEEDMSG_FLAG_READ ) = = 0 ) + + ( * unreadCount ) ;
}
2012-08-02 09:17:53 -04:00
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : getFeedMsgList ( uint32_t feedId , std : : list < FeedMsgInfo > & msgInfos )
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getFeedMsgList - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; + + msgIt ) {
2012-08-02 09:17:53 -04:00
RsFeedReaderMsg * mi = msgIt - > second ;
if ( mi - > flag & RS_FEEDMSG_FLAG_DELETED ) {
continue ;
}
FeedMsgInfo msgInfo ;
feedMsgToInfo ( mi , msgInfo ) ;
msgInfos . push_back ( msgInfo ) ;
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : getFeedMsgIdList ( uint32_t feedId , std : : list < std : : string > & msgIds )
2012-08-13 17:35:11 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-13 17:35:11 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getFeedMsgList - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; + + msgIt ) {
2012-08-13 17:35:11 -04:00
RsFeedReaderMsg * mi = msgIt - > second ;
if ( mi - > flag & RS_FEEDMSG_FLAG_DELETED ) {
continue ;
}
msgIds . push_back ( mi - > msgId ) ;
}
return true ;
}
2012-08-02 09:17:53 -04:00
static bool canProcessFeed ( RsFeedReaderFeed * fi )
{
2012-08-13 17:35:11 -04:00
if ( fi - > preview ) {
/* preview feed */
return false ;
}
2012-08-02 09:17:53 -04:00
if ( fi - > flag & RS_FEED_FLAG_DEACTIVATED ) {
/* deactivated */
return false ;
}
if ( fi - > workstate ! = RsFeedReaderFeed : : WAITING ) {
/* should be working */
return false ;
}
if ( fi - > flag & RS_FEED_FLAG_FOLDER ) {
/* folder */
return false ;
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : processFeed ( uint32_t feedId )
2012-08-02 09:17:53 -04:00
{
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > feedToDownload ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt ;
2012-08-02 09:17:53 -04:00
2020-11-08 07:22:59 -05:00
if ( feedId = = 0 ) {
2012-08-02 09:17:53 -04:00
/* process all feeds */
for ( feedIt = mFeeds . begin ( ) ; feedIt ! = mFeeds . end ( ) ; + + feedIt ) {
RsFeedReaderFeed * fi = feedIt - > second ;
if ( ! canProcessFeed ( fi ) ) {
continue ;
}
/* add to download list */
feedToDownload . push_back ( fi - > feedId ) ;
fi - > workstate = RsFeedReaderFeed : : WAITING_TO_DOWNLOAD ;
fi - > content . clear ( ) ;
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::processFeed - starting feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) " < < std : : endl ;
# endif
}
} else {
feedIt = mFeeds . find ( feedId ) ;
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::processFeed - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
if ( fi - > flag & RS_FEED_FLAG_FOLDER ) {
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > feedIds ;
2012-08-02 09:17:53 -04:00
feedIds . push_back ( fi - > feedId ) ;
while ( ! feedIds . empty ( ) ) {
2020-11-08 07:22:59 -05:00
uint32_t parentId = feedIds . front ( ) ;
2012-08-02 09:17:53 -04:00
feedIds . pop_front ( ) ;
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt1 ;
2012-08-02 09:17:53 -04:00
for ( feedIt1 = mFeeds . begin ( ) ; feedIt1 ! = mFeeds . end ( ) ; + + feedIt1 ) {
RsFeedReaderFeed * fi1 = feedIt1 - > second ;
if ( fi1 - > parentId = = parentId ) {
if ( fi1 - > flag & RS_FEED_FLAG_FOLDER ) {
feedIds . push_back ( fi1 - > feedId ) ;
} else {
if ( canProcessFeed ( fi1 ) ) {
fi1 - > workstate = RsFeedReaderFeed : : WAITING_TO_DOWNLOAD ;
fi1 - > content . clear ( ) ;
feedToDownload . push_back ( fi1 - > feedId ) ;
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::processFeed - starting feed " < < fi1 - > feedId < < " ( " < < fi1 - > name < < " ) " < < std : : endl ;
# endif
}
}
}
}
}
} else {
if ( canProcessFeed ( fi ) ) {
fi - > workstate = RsFeedReaderFeed : : WAITING_TO_DOWNLOAD ;
fi - > content . clear ( ) ;
feedToDownload . push_back ( fi - > feedId ) ;
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::processFeed - starting feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) " < < std : : endl ;
# endif
}
}
}
}
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > notifyIds ;
std : : list < uint32_t > : : iterator it ;
2012-08-02 09:17:53 -04:00
if ( ! feedToDownload . empty ( ) ) {
RsStackMutex stack ( mDownloadMutex ) ; /******* LOCK STACK MUTEX *********/
for ( it = feedToDownload . begin ( ) ; it ! = feedToDownload . end ( ) ; + + it ) {
if ( std : : find ( mDownloadFeeds . begin ( ) , mDownloadFeeds . end ( ) , * it ) = = mDownloadFeeds . end ( ) ) {
mDownloadFeeds . push_back ( * it ) ;
notifyIds . push_back ( * it ) ;
}
}
}
if ( mNotify ) {
for ( it = notifyIds . begin ( ) ; it ! = notifyIds . end ( ) ; + + it ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( * it , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : setMessageRead ( uint32_t feedId , const std : : string & msgId , bool read )
2012-08-02 09:17:53 -04:00
{
bool changed = false ;
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setMessageRead - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
msgIt = fi - > msgs . find ( msgId ) ;
if ( msgIt = = fi - > msgs . end ( ) ) {
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setMessageRead - msg " < < msgId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderMsg * mi = msgIt - > second ;
uint32_t oldFlag = mi - > flag ;
mi - > flag & = ~ RS_FEEDMSG_FLAG_NEW ;
if ( read ) {
/* remove flag new */
mi - > flag | = RS_FEEDMSG_FLAG_READ ;
} else {
mi - > flag & = ~ RS_FEEDMSG_FLAG_READ ;
}
changed = ( mi - > flag ! = oldFlag ) ;
}
if ( changed ) {
IndicateConfigChanged ( ) ;
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
mNotify - > notifyMsgChanged ( feedId , msgId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : retransformMsg ( uint32_t feedId , const std : : string & msgId )
2013-01-21 19:11:43 -05:00
{
bool msgChanged = false ;
bool feedChanged = false ;
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2013-01-21 19:11:43 -05:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setMessageRead - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
msgIt = fi - > msgs . find ( msgId ) ;
if ( msgIt = = fi - > msgs . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setMessageRead - msg " < < msgId < < " not found " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderMsg * mi = msgIt - > second ;
std : : string errorString ;
std : : string descriptionTransformed = mi - > descriptionTransformed ;
if ( p3FeedReaderThread : : processTransformation ( * fi , mi , errorString ) = = RS_FEED_ERRORSTATE_OK ) {
if ( mi - > descriptionTransformed ! = descriptionTransformed ) {
msgChanged = true ;
}
} else {
if ( ! errorString . empty ( ) ) {
fi - > errorString = errorString ;
feedChanged = true ;
}
}
}
if ( feedChanged | | msgChanged ) {
IndicateConfigChanged ( ) ;
if ( mNotify ) {
if ( feedChanged ) {
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
}
if ( msgChanged ) {
mNotify - > notifyMsgChanged ( feedId , msgId , NOTIFY_TYPE_MOD ) ;
}
}
}
return true ;
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : clearMessageCache ( uint32_t feedId )
2014-11-24 17:40:29 -05:00
{
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::clearMessageCache - feed id " < < feedId < < std : : endl ;
# endif
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt = mFeeds . find ( feedId ) ;
2014-11-24 17:40:29 -05:00
if ( feedIt = = mFeeds . end ( ) ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::clearMessageCache - feed id " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
if ( feedIt - > second - > flag & RS_FEED_FLAG_FOLDER ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::clearMessageCache - feed " < < feedIt - > second - > name < < " is a folder " < < std : : endl ;
# endif
return false ;
}
RsFeedReaderFeed * fi = feedIt - > second ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; ) {
RsFeedReaderMsg * mi = msgIt - > second ;
if ( mi - > flag & RS_FEEDMSG_FLAG_DELETED ) {
delete ( mi ) ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator deleteIt = msgIt + + ;
fi - > msgs . erase ( deleteIt ) ;
continue ;
}
+ + msgIt ;
}
}
IndicateConfigChanged ( ) ;
return true ;
}
2012-09-04 19:53:04 -04:00
RsFeedReaderErrorState p3FeedReader : : processXPath ( const std : : list < std : : string > & xpathsToUse , const std : : list < std : : string > & xpathsToRemove , std : : string & description , std : : string & errorString )
{
return p3FeedReaderThread : : processXPath ( xpathsToUse , xpathsToRemove , description , errorString ) ;
}
2013-01-21 19:11:43 -05:00
RsFeedReaderErrorState p3FeedReader : : processXslt ( const std : : string & xslt , std : : string & description , std : : string & errorString )
{
return p3FeedReaderThread : : processXslt ( xslt , description , errorString ) ;
}
2012-08-02 09:17:53 -04:00
/***************************************************************************/
/****************************** p3Service **********************************/
/***************************************************************************/
int p3FeedReader : : tick ( )
{
/* clean feeds */
cleanFeeds ( ) ;
2012-08-13 17:35:11 -04:00
/* check feeds for update interval */
2012-08-02 09:17:53 -04:00
time_t currentTime = time ( NULL ) ;
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > feedToDownload ;
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
for ( feedIt = mFeeds . begin ( ) ; feedIt ! = mFeeds . end ( ) ; + + feedIt ) {
RsFeedReaderFeed * fi = feedIt - > second ;
if ( ! canProcessFeed ( fi ) ) {
continue ;
}
uint32_t updateInterval ;
if ( fi - > flag & RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL ) {
updateInterval = mStandardUpdateInterval ;
} else {
updateInterval = fi - > updateInterval ;
}
2012-08-10 14:06:29 -04:00
if ( updateInterval = = 0 ) {
continue ;
}
2012-08-02 09:17:53 -04:00
if ( fi - > lastUpdate = = 0 | | fi - > lastUpdate + ( long ) updateInterval < = currentTime ) {
/* add to download list */
feedToDownload . push_back ( fi - > feedId ) ;
fi - > workstate = RsFeedReaderFeed : : WAITING_TO_DOWNLOAD ;
fi - > content . clear ( ) ;
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::tick - starting feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) " < < std : : endl ;
# endif
}
}
}
2020-11-08 07:22:59 -05:00
std : : list < uint32_t > notifyIds ;
std : : list < uint32_t > : : iterator it ;
2012-08-02 09:17:53 -04:00
if ( ! feedToDownload . empty ( ) ) {
RsStackMutex stack ( mDownloadMutex ) ; /******* LOCK STACK MUTEX *********/
for ( it = feedToDownload . begin ( ) ; it ! = feedToDownload . end ( ) ; + + it ) {
if ( std : : find ( mDownloadFeeds . begin ( ) , mDownloadFeeds . end ( ) , * it ) = = mDownloadFeeds . end ( ) ) {
mDownloadFeeds . push_back ( * it ) ;
notifyIds . push_back ( * it ) ;
}
}
}
if ( mNotify ) {
for ( it = notifyIds . begin ( ) ; it ! = notifyIds . end ( ) ; + + it ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( * it , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
}
return 0 ;
}
void p3FeedReader : : cleanFeeds ( )
{
time_t currentTime = time ( NULL ) ;
if ( mLastClean = = 0 | | mLastClean + FEEDREADER_CLEAN_INTERVAL < = currentTime ) {
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
2020-11-08 07:22:59 -05:00
std : : list < std : : pair < uint32_t , std : : string > > removedMsgIds ;
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt ;
2012-08-02 09:17:53 -04:00
for ( feedIt = mFeeds . begin ( ) ; feedIt ! = mFeeds . end ( ) ; + + feedIt ) {
RsFeedReaderFeed * fi = feedIt - > second ;
uint32_t storageTime = 0 ;
if ( fi - > flag & RS_FEED_FLAG_STANDARD_STORAGE_TIME ) {
storageTime = mStandardStorageTime ;
} else {
storageTime = fi - > storageTime ;
}
if ( storageTime > 0 ) {
uint32_t removedMsgs = 0 ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; ) {
2012-08-02 09:17:53 -04:00
RsFeedReaderMsg * mi = msgIt - > second ;
if ( mi - > flag & RS_FEEDMSG_FLAG_DELETED ) {
if ( mi - > pubDate < currentTime - ( long ) storageTime ) {
2020-11-08 07:22:59 -05:00
removedMsgIds . push_back ( std : : pair < uint32_t , std : : string > ( fi - > feedId , mi - > msgId ) ) ;
2012-08-02 09:17:53 -04:00
delete ( mi ) ;
std : : map < std : : string , RsFeedReaderMsg * > : : iterator deleteIt = msgIt + + ;
2012-09-04 19:53:04 -04:00
fi - > msgs . erase ( deleteIt ) ;
2012-08-02 09:17:53 -04:00
+ + removedMsgs ;
continue ;
}
}
+ + msgIt ;
}
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::tick - feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) cleaned, " < < removedMsgs < < " messages removed " < < std : : endl ;
# endif
}
}
mLastClean = currentTime ;
if ( removedMsgIds . size ( ) ) {
IndicateConfigChanged ( ) ;
2012-12-27 19:42:27 -05:00
if ( mNotify ) {
2020-11-08 07:22:59 -05:00
std : : list < std : : pair < uint32_t , std : : string > > : : iterator it ;
2012-12-27 19:42:27 -05:00
for ( it = removedMsgIds . begin ( ) ; it ! = removedMsgIds . end ( ) ; + + it ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyMsgChanged ( it - > first , it - > second , NOTIFY_TYPE_DEL ) ;
2012-12-27 19:42:27 -05:00
}
2012-08-02 09:17:53 -04:00
}
}
}
}
/***************************************************************************/
/****************************** p3Config ***********************************/
/***************************************************************************/
RsSerialiser * p3FeedReader : : setupSerialiser ( )
{
RsSerialiser * rss = new RsSerialiser ( ) ;
/* add in the types we need! */
rss - > addSerialType ( new RsFeedReaderSerialiser ( ) ) ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
2013-05-01 17:16:46 -04:00
bool p3FeedReader : : saveList ( bool & cleanup , std : : list < RsItem * > & saveData )
2012-08-02 09:17:53 -04:00
{
mFeedReaderMtx . lock ( ) ; /*********************** LOCK *******/
2013-05-01 17:16:46 -04:00
if ( mSaveInBackground ) {
cleanup = true ;
} else {
cleanup = false ;
}
2012-08-02 09:17:53 -04:00
RsConfigKeyValueSet * rskv = new RsConfigKeyValueSet ( ) ;
RsTlvKeyValue kv ;
kv . key = " StandardStorageTime " ;
rs_sprintf ( kv . value , " %u " , mStandardStorageTime ) ;
rskv - > tlvkvs . pairs . push_back ( kv ) ;
kv . key = " StandardUpdateInterval " ;
rs_sprintf ( kv . value , " %u " , mStandardUpdateInterval ) ;
rskv - > tlvkvs . pairs . push_back ( kv ) ;
kv . key = " StandardUseProxy " ;
rs_sprintf ( kv . value , " %hu " , mStandardUseProxy ? 1 : 0 ) ;
rskv - > tlvkvs . pairs . push_back ( kv ) ;
kv . key = " StandardProxyAddress " ;
rs_sprintf ( kv . value , " %s " , mStandardProxyAddress . c_str ( ) ) ;
rskv - > tlvkvs . pairs . push_back ( kv ) ;
kv . key = " StandardProxyPort " ;
rs_sprintf ( kv . value , " %hu " , mStandardProxyPort ) ;
rskv - > tlvkvs . pairs . push_back ( kv ) ;
2013-05-01 17:16:46 -04:00
kv . key = " SaveInBackground " ;
rs_sprintf ( kv . value , " %hu " , mSaveInBackground ? 1 : 0 ) ;
rskv - > tlvkvs . pairs . push_back ( kv ) ;
2012-08-02 09:17:53 -04:00
/* Add KeyValue to saveList */
saveData . push_back ( rskv ) ;
2013-05-01 17:16:46 -04:00
if ( ! cleanup ) {
cleanSaveData . push_back ( rskv ) ;
}
2012-08-02 09:17:53 -04:00
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it1 ;
2012-08-02 09:17:53 -04:00
for ( it1 = mFeeds . begin ( ) ; it1 ! = mFeeds . end ( ) ; + + it1 ) {
RsFeedReaderFeed * fi = it1 - > second ;
2012-08-13 17:35:11 -04:00
if ( fi - > preview ) {
continue ;
}
2013-05-01 17:16:46 -04:00
if ( cleanup ) {
saveData . push_back ( new RsFeedReaderFeed ( * fi ) ) ;
} else {
saveData . push_back ( fi ) ;
}
2012-08-02 09:17:53 -04:00
std : : map < std : : string , RsFeedReaderMsg * > : : iterator it2 ;
2012-09-04 19:53:04 -04:00
for ( it2 = fi - > msgs . begin ( ) ; it2 ! = fi - > msgs . end ( ) ; + + it2 ) {
2013-05-01 17:16:46 -04:00
RsFeedReaderMsg * msg = it2 - > second ;
if ( cleanup ) {
saveData . push_back ( new RsFeedReaderMsg ( * msg ) ) ;
} else {
saveData . push_back ( msg ) ;
}
2012-08-02 09:17:53 -04:00
}
}
2013-05-01 17:16:46 -04:00
if ( mSaveInBackground ) {
mFeedReaderMtx . unlock ( ) ; /*********************** UNLOCK *******/
}
2012-08-02 09:17:53 -04:00
/* list completed! */
return true ;
}
void p3FeedReader : : saveDone ( )
2013-05-01 17:16:46 -04:00
{
/* clean settings items */
std : : list < RsItem * > : : iterator it ;
for ( it = cleanSaveData . begin ( ) ; it ! = cleanSaveData . end ( ) ; + + it ) {
delete ( * it ) ;
}
cleanSaveData . clear ( ) ;
if ( ! mSaveInBackground ) {
mFeedReaderMtx . unlock ( ) ; /*********************** UNLOCK *******/
}
2012-08-02 09:17:53 -04:00
}
bool p3FeedReader : : loadList ( std : : list < RsItem * > & load )
{
std : : list < RsItem * > : : iterator it ;
RsFeedReaderFeed * fi ;
RsFeedReaderMsg * mi ;
RsConfigKeyValueSet * rskv ;
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::loadList() Item Count: " < < load . size ( ) ;
std : : cerr < < std : : endl ;
# endif
mNextFeedId = 1 ;
mNextMsgId = 1 ;
std : : map < std : : string , RsFeedReaderMsg * > msgs ;
for ( it = load . begin ( ) ; it ! = load . end ( ) ; + + it ) {
/* switch on type */
if ( NULL ! = ( fi = dynamic_cast < RsFeedReaderFeed * > ( * it ) ) ) {
2020-11-08 07:22:59 -05:00
RsStackMutex stack ( mFeedReaderMtx ) ; /********** STACK LOCKED MTX ******/
if ( mFeeds . find ( fi - > feedId ) ! = mFeeds . end ( ) ) {
/* feed with the same id exists */
delete mFeeds [ fi - > feedId ] ;
}
mFeeds [ fi - > feedId ] = fi ;
2012-08-02 09:17:53 -04:00
2020-11-08 07:22:59 -05:00
if ( fi - > feedId + 1 > mNextFeedId ) {
mNextFeedId = fi - > feedId + 1 ;
2012-08-02 09:17:53 -04:00
}
} else if ( NULL ! = ( mi = dynamic_cast < RsFeedReaderMsg * > ( * it ) ) ) {
if ( msgs . find ( mi - > msgId ) ! = msgs . end ( ) ) {
delete msgs [ mi - > msgId ] ;
}
msgs [ mi - > msgId ] = mi ;
} else if ( NULL ! = ( rskv = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ) ) {
std : : list < RsTlvKeyValue > : : iterator kit ;
for ( kit = rskv - > tlvkvs . pairs . begin ( ) ; kit ! = rskv - > tlvkvs . pairs . end ( ) ; kit + + ) {
if ( kit - > key = = " StandardStorageTime " ) {
uint32_t value ;
if ( sscanf ( kit - > value . c_str ( ) , " %u " , & value ) = = 1 ) {
mStandardStorageTime = value ;
}
} else if ( kit - > key = = " StandardUpdateInterval " ) {
uint32_t value ;
if ( sscanf ( kit - > value . c_str ( ) , " %u " , & value ) = = 1 ) {
mStandardUpdateInterval = value ;
}
} else if ( kit - > key = = " StandardUseProxy " ) {
uint16_t value ;
if ( sscanf ( kit - > value . c_str ( ) , " %hu " , & value ) = = 1 ) {
mStandardUseProxy = value = = 1 ? true : false ;
}
} else if ( kit - > key = = " StandardProxyAddress " ) {
mStandardProxyAddress = kit - > value ;
} else if ( kit - > key = = " StandardProxyPort " ) {
uint16_t value ;
if ( sscanf ( kit - > value . c_str ( ) , " %hu " , & value ) = = 1 ) {
mStandardProxyPort = value ;
}
2013-05-01 17:16:46 -04:00
} else if ( kit - > key = = " SaveInBackground " ) {
uint16_t value ;
if ( sscanf ( kit - > value . c_str ( ) , " %hu " , & value ) = = 1 ) {
mSaveInBackground = value = = 1 ? true : false ;
}
2012-08-02 09:17:53 -04:00
}
}
} else {
/* cleanup */
delete ( * it ) ;
}
}
RsStackMutex stack ( mFeedReaderMtx ) ; /********** STACK LOCKED MTX ******/
2014-05-09 19:12:03 -04:00
/* check feeds */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator feedIt ;
2014-05-09 19:12:03 -04:00
for ( feedIt = mFeeds . begin ( ) ; feedIt ! = mFeeds . end ( ) ; + + feedIt ) {
RsFeedReaderFeed * feed = feedIt - > second ;
2020-11-08 07:22:59 -05:00
if ( feed - > parentId ) {
2014-05-09 19:12:03 -04:00
/* check parent */
if ( mFeeds . find ( feed - > parentId ) = = mFeeds . end ( ) ) {
/* parent not found, clear it */
2020-11-08 07:22:59 -05:00
feed - > parentId = 0 ;
2014-05-09 19:12:03 -04:00
}
}
}
/* now sort msgs into feeds */
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
for ( msgIt = msgs . begin ( ) ; msgIt ! = msgs . end ( ) ; + + msgIt ) {
2012-08-02 09:17:53 -04:00
uint32_t msgId = 0 ;
2014-05-09 19:12:03 -04:00
if ( sscanf ( msgIt - > first . c_str ( ) , " %u " , & msgId ) = = 1 ) {
feedIt = mFeeds . find ( msgIt - > second - > feedId ) ;
if ( feedIt = = mFeeds . end ( ) ) {
2012-08-02 09:17:53 -04:00
/* feed does not exist exists */
2014-05-09 19:12:03 -04:00
delete msgIt - > second ;
2012-08-02 09:17:53 -04:00
continue ;
}
2014-05-09 19:12:03 -04:00
feedIt - > second - > msgs [ msgIt - > first ] = msgIt - > second ;
2012-08-02 09:17:53 -04:00
if ( msgId + 1 > mNextMsgId ) {
mNextMsgId = msgId + 1 ;
}
} else {
/* invalid msg id */
2014-05-09 19:12:03 -04:00
delete ( msgIt - > second ) ;
2012-08-02 09:17:53 -04:00
}
}
return true ;
}
/***************************************************************************/
/****************************** internal ***********************************/
/***************************************************************************/
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : getFeedToDownload ( RsFeedReaderFeed & feed , uint32_t neededFeedId )
2012-08-02 09:17:53 -04:00
{
2020-11-08 07:22:59 -05:00
uint32_t feedId = neededFeedId ;
2012-08-02 09:17:53 -04:00
2020-11-08 07:22:59 -05:00
if ( feedId = = 0 ) {
2012-08-02 09:17:53 -04:00
RsStackMutex stack ( mDownloadMutex ) ; /******* LOCK STACK MUTEX *********/
if ( mDownloadFeeds . empty ( ) ) {
/* nothing to download */
return false ;
}
/* get next feed id to download */
feedId = mDownloadFeeds . front ( ) ;
mDownloadFeeds . pop_front ( ) ;
}
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getFeedToDownload - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
2012-08-13 17:35:11 -04:00
/* check state */
2012-08-02 09:17:53 -04:00
if ( it - > second - > workstate ! = RsFeedReaderFeed : : WAITING_TO_DOWNLOAD ) {
std : : cerr < < " p3FeedReader::getFeedToDownload - feed in wrong work state for download " < < it - > second - > workstate < < std : : endl ;
return false ;
}
/* set state to downloading */
it - > second - > workstate = RsFeedReaderFeed : : DOWNLOADING ;
/* return a copy of the feed */
feed = * ( it - > second ) ;
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getFeedToDownload - feed " < < it - > second - > feedId < < " ( " < < it - > second - > name < < " ) is starting to download " < < std : : endl ;
# endif
}
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
return true ;
}
2020-11-08 07:22:59 -05:00
void p3FeedReader : : onDownloadSuccess ( uint32_t feedId , const std : : string & content , std : : string & icon )
2012-08-02 09:17:53 -04:00
{
2012-08-13 17:35:11 -04:00
bool preview ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::onDownloadSuccess - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return ;
}
RsFeedReaderFeed * fi = it - > second ;
fi - > workstate = RsFeedReaderFeed : : WAITING_TO_PROCESS ;
fi - > content = content ;
2012-08-13 17:35:11 -04:00
preview = fi - > preview ;
2012-08-02 09:17:53 -04:00
if ( fi - > icon ! = icon ) {
fi - > icon = icon ;
2012-08-13 17:35:11 -04:00
if ( ! preview ) {
IndicateConfigChanged ( ) ;
}
2012-08-02 09:17:53 -04:00
}
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::onDownloadSuccess - feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) add to process " < < std : : endl ;
# endif
}
2012-08-13 17:35:11 -04:00
if ( ! preview ) {
2012-08-02 09:17:53 -04:00
RsStackMutex stack ( mProcessMutex ) ; /******* LOCK STACK MUTEX *********/
if ( std : : find ( mProcessFeeds . begin ( ) , mProcessFeeds . end ( ) , feedId ) = = mProcessFeeds . end ( ) ) {
mProcessFeeds . push_back ( feedId ) ;
}
}
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
}
2020-11-08 07:22:59 -05:00
void p3FeedReader : : onDownloadError ( uint32_t feedId , RsFeedReaderErrorState result , const std : : string & errorString )
2012-08-02 09:17:53 -04:00
{
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::onDownloadError - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return ;
}
RsFeedReaderFeed * fi = it - > second ;
fi - > workstate = RsFeedReaderFeed : : WAITING ;
fi - > lastUpdate = time ( NULL ) ;
fi - > content . clear ( ) ;
2012-09-04 19:53:04 -04:00
fi - > errorState = result ;
2012-08-13 17:35:11 -04:00
fi - > errorString = errorString ;
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
2012-08-13 17:35:11 -04:00
std : : cerr < < " p3FeedReader::onDownloadError - feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) error download, result = " < < result < < " , errorState = " < < fi - > errorState < < " , error = " < < errorString < < std : : endl ;
2012-08-02 09:17:53 -04:00
# endif
2012-08-13 17:35:11 -04:00
if ( ! fi - > preview ) {
IndicateConfigChanged ( ) ;
}
2012-08-02 09:17:53 -04:00
}
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
}
2020-11-08 07:22:59 -05:00
bool p3FeedReader : : getFeedToProcess ( RsFeedReaderFeed & feed , uint32_t neededFeedId )
2012-08-02 09:17:53 -04:00
{
2020-11-08 07:22:59 -05:00
uint32_t feedId = neededFeedId ;
2012-08-02 09:17:53 -04:00
2020-11-08 07:22:59 -05:00
if ( feedId = = 0 ) {
2012-08-02 09:17:53 -04:00
RsStackMutex stack ( mProcessMutex ) ; /******* LOCK STACK MUTEX *********/
if ( mProcessFeeds . empty ( ) ) {
/* nothing to process */
return false ;
}
/* get next feed id to process */
feedId = mProcessFeeds . front ( ) ;
mProcessFeeds . pop_front ( ) ;
}
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::getFeedToProcess - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return false ;
}
2012-08-13 17:35:11 -04:00
RsFeedReaderFeed * fi = it - > second ;
if ( fi - > workstate ! = RsFeedReaderFeed : : WAITING_TO_PROCESS ) {
std : : cerr < < " p3FeedReader::getFeedToProcess - feed in wrong state for process " < < fi - > workstate < < std : : endl ;
2012-08-02 09:17:53 -04:00
return false ;
}
/* set state to processing */
fi - > workstate = RsFeedReaderFeed : : PROCESSING ;
fi - > errorState = RS_FEED_ERRORSTATE_OK ;
fi - > errorString . clear ( ) ;
/* return a copy of the feed */
feed = * fi ;
# ifdef FEEDREADER_DEBUG
2012-08-13 17:35:11 -04:00
std : : cerr < < " p3FeedReader::getFeedToProcess - feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) is starting to process " < < std : : endl ;
2012-08-02 09:17:53 -04:00
# endif
}
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
return true ;
}
2020-11-08 07:22:59 -05:00
void p3FeedReader : : onProcessSuccess_filterMsg ( uint32_t feedId , std : : list < RsFeedReaderMsg * > & msgs )
2012-08-02 09:17:53 -04:00
{
# ifdef FEEDREADER_DEBUG
2012-08-10 14:06:29 -04:00
std : : cerr < < " p3FeedReader::onProcessSuccess_filterMsg - feed " < < feedId < < " got " < < msgs . size ( ) < < " messages " < < std : : endl ;
2012-08-02 09:17:53 -04:00
# endif
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
2012-08-10 14:06:29 -04:00
std : : cerr < < " p3FeedReader::onProcessSuccess_filterMsg - feed " < < feedId < < " not found " < < std : : endl ;
2012-08-02 09:17:53 -04:00
# endif
2012-09-04 19:53:04 -04:00
return ;
2012-08-02 09:17:53 -04:00
}
RsFeedReaderFeed * fi = it - > second ;
2012-08-13 17:35:11 -04:00
std : : list < RsFeedReaderMsg * > : : iterator newMsgIt ;
for ( newMsgIt = msgs . begin ( ) ; newMsgIt ! = msgs . end ( ) ; ) {
RsFeedReaderMsg * miNew = * newMsgIt ;
/* search for existing msg */
std : : map < std : : string , RsFeedReaderMsg * > : : iterator msgIt ;
2012-09-04 19:53:04 -04:00
for ( msgIt = fi - > msgs . begin ( ) ; msgIt ! = fi - > msgs . end ( ) ; + + msgIt ) {
2012-08-13 17:35:11 -04:00
RsFeedReaderMsg * mi = msgIt - > second ;
if ( mi - > title = = miNew - > title & & mi - > link = = miNew - > link & & mi - > author = = miNew - > author ) {
/* msg exist */
break ;
}
}
2012-09-04 19:53:04 -04:00
if ( msgIt ! = fi - > msgs . end ( ) ) {
2012-08-13 17:35:11 -04:00
/* msg exists */
delete ( miNew ) ;
newMsgIt = msgs . erase ( newMsgIt ) ;
} else {
+ + newMsgIt ;
}
}
fi - > content . clear ( ) ;
fi - > errorString . clear ( ) ;
if ( ! fi - > preview ) {
IndicateConfigChanged ( ) ;
}
}
}
2020-11-08 07:22:59 -05:00
void p3FeedReader : : onProcessSuccess_addMsgs ( uint32_t feedId , std : : list < RsFeedReaderMsg * > & msgs , bool single )
2012-08-13 17:35:11 -04:00
{
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::onProcessSuccess_addMsgs - feed " < < feedId < < " got " < < msgs . size ( ) < < " messages " < < std : : endl ;
# endif
std : : list < std : : string > addedMsgs ;
std : : string forumId ;
2023-04-10 18:36:41 -04:00
RsGxsId forumAuthorId ;
2012-08-13 17:35:11 -04:00
std : : list < RsFeedReaderMsg > forumMsgs ;
2023-04-10 18:36:41 -04:00
std : : string postedId ;
RsGxsId postedAuthorId ;
std : : list < RsFeedReaderMsg > postedMsgs ;
uint32_t feedFlag = 0 ;
2012-08-13 17:35:11 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-13 17:35:11 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::onProcessSuccess_addMsgs - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return ;
}
RsFeedReaderFeed * fi = it - > second ;
bool forum = ( fi - > flag & RS_FEED_FLAG_FORUM ) & & ! fi - > preview ;
2023-04-10 18:36:41 -04:00
bool posted = ( fi - > flag & RS_FEED_FLAG_POSTED ) & & ! fi - > preview ;
2012-08-13 17:35:11 -04:00
RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK ;
2023-04-10 18:36:41 -04:00
feedFlag = fi - > flag ;
2012-08-13 17:35:11 -04:00
2012-09-04 19:53:04 -04:00
if ( forum & & ! msgs . empty ( ) ) {
2014-01-03 10:05:48 -05:00
if ( mForums ) {
2014-11-24 17:40:29 -05:00
if ( ! fi - > forumId . empty ( ) ) {
2014-01-03 10:05:48 -05:00
/* check forum */
2014-11-24 17:40:29 -05:00
RsGxsForumGroup forumGroup ;
if ( getForumGroup ( RsGxsGroupId ( fi - > forumId ) , forumGroup ) ) {
if ( IS_GROUP_PUBLISHER ( forumGroup . mMeta . mSubscribeFlags ) & & IS_GROUP_ADMIN ( forumGroup . mMeta . mSubscribeFlags ) ) {
2014-01-03 10:05:48 -05:00
forumId = fi - > forumId ;
2023-04-10 18:36:41 -04:00
forumAuthorId = forumGroup . mMeta . mAuthorId ;
2015-06-09 14:03:09 -04:00
2023-04-10 18:36:41 -04:00
if ( forumAuthorId . isNull ( ) ) {
2015-06-09 14:03:09 -04:00
errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR ;
}
2014-11-24 17:40:29 -05:00
} else {
errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN ;
2014-01-03 10:05:48 -05:00
}
} else {
errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND ;
}
2014-11-24 17:40:29 -05:00
} else {
std : : cerr < < " p3FeedReader::onProcessSuccess_addMsgs - forum id is empty ( " < < fi - > name < < " ) " < < std : : endl ;
errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND ;
2012-08-02 09:17:53 -04:00
}
2014-01-03 10:05:48 -05:00
} else {
std : : cerr < < " p3FeedReader::onProcessSuccess_addMsgs - can't process forum, member mForums is not set " < < std : : endl ;
2012-08-02 09:17:53 -04:00
}
}
2023-04-10 18:36:41 -04:00
if ( posted & & ! msgs . empty ( ) ) {
if ( mPosted ) {
if ( ! fi - > postedId . 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 ;
}
}
2012-08-02 09:17:53 -04:00
/* process msgs */
if ( errorState = = RS_FEED_ERRORSTATE_OK ) {
2012-08-13 17:35:11 -04:00
/* process msgs */
2012-08-10 14:06:29 -04:00
# ifdef FEEDREADER_DEBUG
2012-08-13 17:35:11 -04:00
uint32_t newMsgs = 0 ;
2012-08-10 14:06:29 -04:00
# endif
2012-09-04 19:53:04 -04:00
std : : list < RsFeedReaderMsg * > : : iterator newMsgIt ;
for ( newMsgIt = msgs . begin ( ) ; newMsgIt ! = msgs . end ( ) ; ) {
RsFeedReaderMsg * miNew = * newMsgIt ;
/* add new msg */
if ( fi - > preview ) {
rs_sprintf ( miNew - > msgId , " preview%d " , mNextPreviewMsgId - - ) ;
} else {
rs_sprintf ( miNew - > msgId , " %lu " , mNextMsgId + + ) ;
}
2023-04-10 18:36:41 -04:00
if ( forum | | posted ) {
2012-09-04 19:53:04 -04:00
miNew - > flag = RS_FEEDMSG_FLAG_DELETED ;
2023-04-10 18:36:41 -04:00
if ( forum ) {
forumMsgs . push_back ( * miNew ) ;
}
if ( posted ) {
postedMsgs . push_back ( * miNew ) ;
}
2013-01-21 19:11:43 -05:00
miNew - > description . clear ( ) ;
miNew - > descriptionTransformed . clear ( ) ;
2012-09-04 19:53:04 -04:00
} else {
miNew - > flag = RS_FEEDMSG_FLAG_NEW ;
addedMsgs . push_back ( miNew - > msgId ) ;
}
fi - > msgs [ miNew - > msgId ] = miNew ;
newMsgIt = msgs . erase ( newMsgIt ) ;
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
2012-09-04 19:53:04 -04:00
+ + newMsgs ;
2012-08-02 09:17:53 -04:00
# endif
2012-09-04 19:53:04 -04:00
}
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
2012-09-04 19:53:04 -04:00
std : : cerr < < " p3FeedReader::onProcessSuccess_addMsgs - feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) added " < < newMsgs < < " / " < < msgs . size ( ) < < " messages " < < std : : endl ;
2012-08-02 09:17:53 -04:00
# endif
}
2012-08-13 17:35:11 -04:00
if ( ! single ) {
fi - > workstate = RsFeedReaderFeed : : WAITING ;
fi - > content . clear ( ) ;
fi - > errorState = errorState ;
fi - > lastUpdate = time ( NULL ) ;
}
2012-08-02 09:17:53 -04:00
2012-08-13 17:35:11 -04:00
if ( ! fi - > preview ) {
IndicateConfigChanged ( ) ;
}
2012-08-02 09:17:53 -04:00
}
2014-11-24 17:40:29 -05:00
if ( ! forumId . empty ( ) & & ! forumMsgs . empty ( ) ) {
if ( mForums ) {
/* a bit tricky */
RsGenExchange * genExchange = dynamic_cast < RsGenExchange * > ( mForums ) ;
if ( genExchange ) {
/* add messages as forum messages */
std : : list < RsFeedReaderMsg > : : iterator msgIt ;
for ( msgIt = forumMsgs . begin ( ) ; msgIt ! = forumMsgs . end ( ) ; + + msgIt ) {
RsFeedReaderMsg & mi = * msgIt ;
/* convert to forum messages */
RsGxsForumMsg forumMsg ;
forumMsg . mMeta . mGroupId = RsGxsGroupId ( forumId ) ;
forumMsg . mMeta . mMsgName = mi . title ;
2023-04-10 18:36:41 -04:00
forumMsg . mMeta . mAuthorId = forumAuthorId ;
2014-11-24 17:40:29 -05:00
std : : string description = mi . descriptionTransformed . empty ( ) ? mi . description : mi . descriptionTransformed ;
/* add link */
if ( ! mi . link . empty ( ) ) {
description + = " <br><a href= \" " + mi . link + " \" > " + mi . link + " </a> " ;
}
forumMsg . mMsg = description ;
uint32_t token ;
2023-04-10 18:36:41 -04:00
if ( mForums - > createMsg ( token , forumMsg ) & & waitForToken ( mForums , token ) ) {
2014-11-24 17:40:29 -05:00
RsGxsGrpMsgIdPair msgPair ;
if ( mForums - > 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 forum message " < < mi . title < < " for feed " < < forumId < < std : : endl ;
# endif
}
}
} else {
std : : cerr < < " p3FeedReader::onProcessSuccess_addMsgs - can't process forum, member mForums is not derived from RsGenExchange " < < std : : endl ;
}
} else {
std : : cerr < < " p3FeedReader::onProcessSuccess_addMsgs - can't process forum, member mForums is not set " < < std : : endl ;
}
}
2012-08-02 09:17:53 -04:00
2023-04-10 18:36:41 -04:00
if ( ! postedId . empty ( ) & & ! postedMsgs . empty ( ) ) {
if ( mPosted ) {
/* a bit tricky */
RsGenExchange * genExchange = dynamic_cast < RsGenExchange * > ( mPosted ) ;
if ( genExchange ) {
/* add messages as posted messages */
std : : list < RsFeedReaderMsg > : : 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 ;
}
}
2012-08-02 09:17:53 -04:00
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
std : : list < std : : string > : : iterator it ;
for ( it = addedMsgs . begin ( ) ; it ! = addedMsgs . end ( ) ; + + it ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyMsgChanged ( feedId , * it , NOTIFY_TYPE_ADD ) ;
2012-08-02 09:17:53 -04:00
}
}
}
2020-11-08 07:22:59 -05:00
void p3FeedReader : : onProcessError ( uint32_t feedId , RsFeedReaderErrorState result , const std : : string & errorString )
2012-08-02 09:17:53 -04:00
{
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::onProcessError - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return ;
}
RsFeedReaderFeed * fi = it - > second ;
fi - > workstate = RsFeedReaderFeed : : WAITING ;
fi - > lastUpdate = time ( NULL ) ;
fi - > content . clear ( ) ;
2012-09-04 19:53:04 -04:00
fi - > errorState = result ;
2012-08-13 17:35:11 -04:00
fi - > errorString = errorString ;
2012-08-02 09:17:53 -04:00
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::onProcessError - feed " < < fi - > feedId < < " ( " < < fi - > name < < " ) error process, result = " < < result < < " , errorState = " < < fi - > errorState < < std : : endl ;
# endif
2012-08-13 17:35:11 -04:00
if ( ! fi - > preview ) {
IndicateConfigChanged ( ) ;
}
2012-08-02 09:17:53 -04:00
}
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
}
2020-11-08 07:22:59 -05:00
void p3FeedReader : : setFeedInfo ( uint32_t feedId , const std : : string & name , const std : : string & description )
2012-08-02 09:17:53 -04:00
{
bool changed = false ;
2012-08-13 17:35:11 -04:00
bool preview ;
2012-08-02 09:17:53 -04:00
std : : string forumId ;
2014-11-24 17:40:29 -05:00
std : : string forumName ;
std : : string forumDescription ;
2023-04-10 18:36:41 -04:00
std : : string postedId ;
std : : string postedName ;
std : : string postedDescription ;
2012-08-02 09:17:53 -04:00
{
RsStackMutex stack ( mFeedReaderMtx ) ; /******* LOCK STACK MUTEX *********/
/* find feed */
2020-11-08 07:22:59 -05:00
std : : map < uint32_t , RsFeedReaderFeed * > : : iterator it = mFeeds . find ( feedId ) ;
2012-08-02 09:17:53 -04:00
if ( it = = mFeeds . end ( ) ) {
/* feed not found */
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeedInfo - feed " < < feedId < < " not found " < < std : : endl ;
# endif
return ;
}
RsFeedReaderFeed * fi = it - > second ;
2012-08-13 17:35:11 -04:00
preview = fi - > preview ;
2012-08-02 09:17:53 -04:00
if ( fi - > name ! = name ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeedInfo - feed " < < fi - > feedId < < " changed name from " < < fi - > name < < " to " < < name < < std : : endl ;
# endif
fi - > name = name ;
changed = true ;
}
if ( fi - > description ! = description ) {
# ifdef FEEDREADER_DEBUG
std : : cerr < < " p3FeedReader::setFeedInfo - feed " < < fi - > feedId < < " changed description from " < < fi - > description < < " to " < < description < < std : : endl ;
# endif
fi - > description = description ;
changed = true ;
}
2014-11-24 17:40:29 -05:00
if ( ( fi - > flag & RS_FEED_FLAG_FORUM ) & & ( fi - > flag & RS_FEED_FLAG_UPDATE_FORUM_INFO ) & & ! fi - > forumId . empty ( ) & & ! preview ) {
/* change forum too */
forumId = fi - > forumId ;
forumName = fi - > name ;
forumDescription = fi - > description ;
forumName . insert ( 0 , FEEDREADER_FORUM_PREFIX ) ;
}
2023-04-10 18:36:41 -04:00
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 ) ;
}
2012-08-02 09:17:53 -04:00
}
if ( changed ) {
2012-08-13 17:35:11 -04:00
if ( ! preview ) {
IndicateConfigChanged ( ) ;
}
2012-08-02 09:17:53 -04:00
if ( mNotify ) {
2013-01-05 21:30:10 -05:00
mNotify - > notifyFeedChanged ( feedId , NOTIFY_TYPE_MOD ) ;
2012-08-02 09:17:53 -04:00
}
}
2014-11-24 17:40:29 -05:00
if ( ! forumId . empty ( ) ) {
RsGxsForumGroup forumGroup ;
if ( getForumGroup ( RsGxsGroupId ( forumId ) , forumGroup ) ) {
updateForumGroup ( forumGroup , forumName , forumDescription ) ;
}
//TODO: error
}
2023-04-10 18:36:41 -04:00
if ( ! postedId . empty ( ) ) {
RsPostedGroup postedGroup ;
if ( getPostedGroup ( RsGxsGroupId ( postedId ) , postedGroup ) ) {
updatePostedGroup ( postedGroup , postedName , postedDescription ) ;
}
//TODO: error
}
2014-11-24 17:40:29 -05:00
}
bool p3FeedReader : : getForumGroup ( const RsGxsGroupId & groupId , RsGxsForumGroup & forumGroup )
{
if ( ! mForums ) {
std : : cerr < < " p3FeedReader::getForumGroup - can't get forum group " < < groupId . toStdString ( ) < < " , member mForums is not set " < < std : : endl ;
return false ;
}
if ( groupId . isNull ( ) ) {
std : : cerr < < " p3FeedReader::getForumGroup - group id is not valid " < < std : : endl ;
return false ;
}
std : : list < RsGxsGroupId > grpIds ;
grpIds . push_back ( groupId ) ;
RsTokReqOptions opts ;
opts . mReqType = GXS_REQUEST_TYPE_GROUP_DATA ;
uint32_t token ;
mForums - > getTokenService ( ) - > requestGroupInfo ( token , RS_TOKREQ_ANSTYPE_SUMMARY , opts , grpIds ) ;
2023-04-10 18:36:41 -04:00
if ( ! waitForToken ( mForums , token ) ) {
2014-11-24 17:40:29 -05:00
std : : cerr < < " p3FeedReader::getForumGroup - waitForToken for request failed " < < std : : endl ;
return false ;
}
std : : vector < RsGxsForumGroup > groups ;
if ( ! mForums - > getGroupData ( token , groups ) ) {
std : : cerr < < " p3FeedReader::getForumGroup - Error getting data " < < std : : endl ;
return false ;
}
if ( groups . size ( ) ! = 1 ) {
std : : cerr < < " p3FeedReader::getForumGroup - Wrong number of items " < < std : : endl ;
return false ;
}
forumGroup = groups [ 0 ] ;
return true ;
}
bool p3FeedReader : : updateForumGroup ( const RsGxsForumGroup & forumGroup , const std : : string & groupName , const std : : string & groupDescription )
{
if ( ! mForums ) {
std : : cerr < < " p3FeedReader::updateForumGroup - can't change forum " < < forumGroup . mMeta . mGroupId . toStdString ( ) < < " , member mForums is not set " < < std : : endl ;
return false ;
}
if ( forumGroup . mMeta . mGroupName = = groupName & & forumGroup . mDescription = = groupDescription ) {
/* No change */
return true ;
}
RsGxsForumGroup newForumGroup = forumGroup ;
newForumGroup . mMeta . mGroupName = groupName ;
newForumGroup . mDescription = groupDescription ;
uint32_t token ;
if ( ! mForums - > updateGroup ( token , newForumGroup ) ) {
std : : cerr < < " p3FeedReader::updateForumGroup - can't change forum " < < newForumGroup . mMeta . mGroupId . toStdString ( ) < < std : : endl ;
return false ;
}
2023-04-10 18:36:41 -04:00
if ( ! waitForToken ( mForums , token ) ) {
2014-11-24 17:40:29 -05:00
std : : cerr < < " p3FeedReader::updateForumGroup - waitForToken for update failed " < < std : : endl ;
return false ;
}
/* Forum updated */
return true ;
}
2023-04-10 18:36:41 -04:00
bool p3FeedReader : : getPostedGroup ( const RsGxsGroupId & groupId , RsPostedGroup & postedGroup )
2014-11-24 17:40:29 -05:00
{
2023-04-10 18:36:41 -04:00
if ( ! mPosted ) {
std : : cerr < < " p3FeedReader::getPostedGroup - can't get posted group " < < groupId . toStdString ( ) < < " , member mPosted is not set " < < std : : endl ;
return false ;
}
if ( groupId . isNull ( ) ) {
std : : cerr < < " p3FeedReader::getPostedGroup - group id is not valid " < < std : : endl ;
return false ;
}
std : : list < RsGxsGroupId > 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 < RsPostedGroup > 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 ) {
2014-11-24 17:40:29 -05:00
return false ;
}
2023-04-10 18:36:41 -04:00
RsTokenService * service = interface - > getTokenService ( ) ;
2014-11-24 17:40:29 -05:00
int count = MAX_REQUEST_AGE * 2 ;
while ( ! mStopped ) {
uint32_t status = service - > requestStatus ( token ) ;
2018-06-24 12:56:48 -04:00
if ( status = = RsTokenService : : FAILED ) {
2014-11-24 17:40:29 -05:00
break ;
}
2018-06-24 12:56:48 -04:00
if ( status = = RsTokenService : : COMPLETE ) {
2014-11-24 17:40:29 -05:00
return true ;
}
if ( count - - < = 0 ) {
break ;
}
2018-01-27 14:22:31 -05:00
rstime : : rs_usleep ( 500 * 1000 ) ; // sleep for 500 msec
2014-11-24 17:40:29 -05:00
}
return false ;
2012-08-02 09:17:53 -04:00
}