コード例 #1
0
MojErr MovePopEmailsCommand::EmailsMovedResponse(MojObject& response, MojErr err)
{
	try {
		ErrorToException(err);

		ActivityBuilder ab;
		m_client.GetActivityBuilderFactory()->BuildMoveEmailsWatch(ab);
		m_activity->UpdateAndComplete(m_client, ab.GetActivityObject());

		m_msg->replySuccess();

		if (m_inboxEmailsMoved.size() > 0) {
			// add the list of UIDs into UidCache
			GetUidCache();
		} else {
			Complete();
		}
	} catch (const std::exception& ex) {
		m_msg->replyError(MojErrInternal, ex.what());
		Failure(ex);
	} catch (...) {
		m_msg->replyError(MojErrInternal);
		Failure(MailException("unknown exception", __FILE__, __LINE__));
	}

	return MojErrNone;
}
コード例 #2
0
void ScheduleRetryCommand::ScheduleRetry()
{
	ActivityBuilder ab;

	// Get current retry interval from account
	EmailAccount::RetryStatus retryStatus = m_client.GetAccount()->GetRetry();

	int interval = retryStatus.GetInterval();

	if(interval <= INITIAL_RETRY_SECONDS) {
		interval = INITIAL_RETRY_SECONDS;
	} else if(interval >= MAX_RETRY_SECONDS) {
		interval = MAX_RETRY_SECONDS;
	} else {
		// TODO: only update this on actual retry?
		interval *= RETRY_MULTIPLIER;
	}

	// Update account just in case it wasn't within the limit
	retryStatus.SetInterval(interval);
	m_client.GetAccount()->SetRetry(retryStatus);

	m_client.GetActivityBuilderFactory()->BuildFolderRetrySync(ab, m_folderId, interval);

	MojErr err;
	MojObject payload;
	err = payload.put("activity", ab.GetActivityObject());
	ErrorToException(err);
	err = payload.put("start", true);
	ErrorToException(err);
	err = payload.put("replace", true);

	MojLogInfo(m_log, "Creating retry activity in activity manager: %s", AsJsonString(payload).c_str());
	m_client.SendRequest(m_scheduleRetrySlot, "com.palm.activitymanager", "create", payload);
}
コード例 #3
0
void PopAccountUpdateCommand::UpdateAccountWatchActivity()
{
	CommandTraceFunction();

	try {
		MojObject revPop;
		MojErr err = m_transportObj.getRequired("_revPop", revPop);
		ErrorToException(err);

		ActivityBuilder ab;
		m_activityBuilderFactory->BuildAccountPrefsWatch(ab, revPop);

		MojObject payload;
		err = payload.put("activity", ab.GetActivityObject());
		ErrorToException(err);
		err = payload.put("start", true);
		ErrorToException(err);
		err = payload.put("replace", true);
		ErrorToException(err);

		m_client.SendRequest(m_createActivitySlot, "com.palm.activitymanager", "create", payload);
	} catch (const std::exception& ex) {
		Failure(ex);
	} catch (...) {
		Failure(MailException("unknown exception", __FILE__, __LINE__));
	}
}
コード例 #4
0
ファイル: SyncSession.cpp プロジェクト: hatsada1/app-services
void SyncSession::UpdateScheduledSyncActivity()
{
	MojLogInfo(m_log, "updating scheduled sync activity on folder %s", AsJsonString(m_folderId).c_str());

	PopClient::AccountPtr account = m_client.GetAccount();
	MojObject accountId = account->GetAccountId();
	ActivityBuilder ab;

	if(!account->IsManualSync()) {
		int interval = account->GetSyncFrequencyMins();

		MojLogInfo(m_log, "setting sync interval to %d minutes", interval);

		m_builderFactory->BuildScheduledSync(ab, interval);

		MojObject actObj = ab.GetActivityObject();;
		MojLogInfo(m_log, "Replacing scheduled activity: %s", AsJsonString(actObj).c_str());

		m_activities->ReplaceActivity(ab.GetName(), actObj);
	} else {
		MojString scheduledActName;
		m_builderFactory->GetScheduledSyncActivityName(scheduledActName);

		// Remove activity
		ActivityPtr activity = m_activities->GetOrCreateActivity(scheduledActName);
		activity->SetEndAction(Activity::EndAction_Cancel);
	}
}
コード例 #5
0
void ImapActivityFactory::SetNetworkRequirements(ActivityBuilder& ab, bool requireFair)
{
	ab.SetRequiresInternet(false);

	if(requireFair && !ImapConfig::GetConfig().GetIgnoreNetworkStatus()) {
		ab.SetRequiresInternetConfidence("fair");
	}
}
コード例 #6
0
void ActivityBuilderFactory::BuildScheduledSync(ActivityBuilder &builder, int intervalMins)
{
	// activity to setup watch
	MojString name;
	GetScheduledSyncActivityName(name);

	// description of watch
	MojString desc;
	GetScheduledSyncActivityDesc(desc);

	// sync interval in seconds
	int intervalSecs = MinsToSecs(intervalMins);

	builder.SetName(name.data());
	builder.SetDescription(desc.data());
	builder.SetPersist(true);
	builder.SetExplicit(true);
	builder.SetRequiresInternet(false);
	builder.SetSyncInterval(0, intervalSecs);
	builder.SetImmediate(true, "low");

	// setup parameters (to be sent when trigger is called)
	MojObject params;
	MojErr err = params.put(PopAccountAdapter::ACCOUNT_ID, m_accountId);
	ErrorToException(err);
	builder.SetCallback(SCHEDULED_SYNC_CALLBACK, params);

	// put accountId in metadata
	MojObject metadata;
	err = metadata.put("accountId", m_accountId);
	ErrorToException(err);
	builder.SetMetadata(metadata);
}
コード例 #7
0
void SmtpActivityFactory::BuildOutboxWatch(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId)
{
	ActivityBuilder actBuilder;

	MojString name;

	name.format(OUTBOX_WATCH_ACTIVITY_FMT, AsJsonString(accountId).c_str());

	ab.SetName(name);
	ab.SetDescription("Watches SMTP outbox for new emails");
	ab.SetPersist(true);
	ab.SetExplicit(true);
	ab.SetRequiresInternet(false); // don't trigger until we also have connectivity
	ab.SetImmediate(true, ActivityBuilder::PRIORITY_LOW);

	// Callback
	MojObject callbackParams;
	MojErr err = callbackParams.put("accountId", accountId);
	ErrorToException(err);
	err = callbackParams.put("folderId", folderId);
	ErrorToException(err);

	ab.SetCallback(OUTBOX_BUS_METHOD, callbackParams);
	ab.SetMetadata(callbackParams);
}
コード例 #8
0
void ActivityBuilderFactory::BuildDeleteEmailsWatch(ActivityBuilder& builder)
{
	MojString name;
	GetDeleteEmailsActivityName(name);

	MojString desc;
	GetDeleteEmailsActivityDesc(desc);

	builder.SetName(name.data());
	builder.SetDescription(desc.data());
	builder.SetPersist(true);
	builder.SetExplicit(true);
	builder.SetImmediate(true, "low");

	// setup trigger
	MojDbQuery trigger;
	MojErr err = trigger.from(PopEmailAdapter::POP_EMAIL_KIND);
	ErrorToException(err);
	err = trigger.where("_del", MojDbQuery::OpEq, true);
	ErrorToException(err);
	builder.SetDatabaseWatchTrigger(trigger);

	// setup parameters (to be sent when trigger is called)
	MojObject params;
	err = params.put(PopFolderAdapter::ACCOUNT_ID, m_accountId);
	ErrorToException(err);
	builder.SetCallback(DELETE_EMAILS_CALLBACK, params);

	// put accountId in metadata
	MojObject metadata;
	err = metadata.put(PopFolderAdapter::ACCOUNT_ID, m_accountId);
	ErrorToException(err);
	builder.SetMetadata(metadata);
}
コード例 #9
0
void ImapActivityFactory::BuildScheduledSync(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId, int seconds, bool requireFair)
{
	MojErr err;

	ab.SetName( GetScheduledSyncName(accountId, folderId) );

	MojString desc;
	err = desc.format("Scheduled sync every %d minutes", seconds/60);
	ErrorToException(err);

	ab.SetDescription(desc.data());
	ab.SetExplicit(true);
	ab.SetPersist(true);
	ab.SetImmediate(true, "low");
	SetNetworkRequirements(ab, requireFair);

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, SCHEDULED_SYNC_NAME, accountId, folderId);
	ab.SetMetadata(metadata);

	// Wakeup
	ab.SetSyncInterval(0, seconds);

	// Callback
	MojObject params;
	err = params.put("accountId", accountId);
	ErrorToException(err);

	ab.SetCallback(SCHEDULED_SYNC_CALLBACK, params);
}
コード例 #10
0
void ActivityBuilderFactory::BuildAccountPrefsWatch(ActivityBuilder& builder, MojObject& accountRev)
{
	MojString name;
	GetAccountPrefsWatchActivityName(name);

	MojString desc;
	GetAccountPrefsWatchActivityDesc(desc);

	builder.SetName(name.data());
	builder.SetDescription(desc.data());
	builder.SetPersist(true);
	builder.SetExplicit(true);
	builder.SetImmediate(true, "low");

	MojDbQuery trigger;
	MojErr err = trigger.from(PopAccountAdapter::POP_ACCOUNT_KIND);
	ErrorToException(err);
	err = trigger.where(PopAccountAdapter::ACCOUNT_ID, MojDbQuery::OpEq, m_accountId);
	ErrorToException(err);
	err = trigger.where("_revPop", MojDbQuery::OpGreaterThan, accountRev);
	ErrorToException(err);
	builder.SetDatabaseWatchTrigger(trigger);

	MojObject params;
	err = params.put(PopAccountAdapter::ACCOUNT_ID, m_accountId);
	ErrorToException(err);
	builder.SetCallback(ACCOUNT_PREFS_WATCH_CALLBACK, params);

	MojObject metadata;
	err = metadata.put(PopAccountAdapter::ACCOUNT_ID, m_accountId);
	ErrorToException(err);
	builder.SetMetadata(metadata);
}
コード例 #11
0
void SmtpSyncOutboxCommand::UpdateAccountWatchActivity()
{
	MojLogInfo(m_log, "UpdatingAccountWatchActivity");
	
	try {
		// accoundId json object
		MojString accountIdJson;
		MojErr err = m_accountId.toJson(accountIdJson);
		ErrorToException(err);

		SmtpActivityFactory factory;
		ActivityBuilder ab;

		factory.BuildSmtpConfigWatch(ab, m_accountId, m_accountRev);

		bool updating = m_accountWatchActivity.get();

		// and either update and complete the updated activity if we had adopted it, or re-create it.
		
		if ( updating ) {
			
			MojLogInfo(m_log, "updating account watch activity");
	
			m_accountWatchActivity->SetSlots(m_accountActivityUpdatedSlot, m_accountActivityErrorSlot);
	
			m_accountWatchActivity->UpdateAndComplete(m_client, ab.GetActivityObject());
			
		} else {
			// Create payload
			MojObject payload;
			err = payload.put("activity", ab.GetActivityObject());
			ErrorToException(err);
			err = payload.put("start", true);
			ErrorToException(err);
			err = payload.put("replace", true);
			ErrorToException(err);
				
			MojLogInfo(m_log, "creating account watch activity");
							
			m_client.SendRequest(m_createAccountWatchActivityResponseSlot, "com.palm.activitymanager", "create", payload);
		}

	} catch (std::exception & e) {
		HandleException(e, __func__);
	} catch (...) {
		HandleException(__func__);
	}
}
コード例 #12
0
void ImapActivityFactory::BuildStartIdle(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId)
{
	MojErr err;

	ab.SetName( GetStartIdleName(accountId, folderId) );
	ab.SetDescription("Starts a push connection when the network is available");
	ab.SetExplicit(false);
	ab.SetPersist(true);
	ab.SetImmediate(true, "low");
	SetNetworkRequirements(ab, false);

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, MAINTAIN_IDLE_NAME, accountId, folderId);
	ab.SetMetadata(metadata);

	// Callback
	MojObject params;
	err = params.put("accountId", accountId);
	ErrorToException(err);
	err = params.put("folderId", folderId);
	ErrorToException(err);

	ab.SetCallback(MAINTAIN_IDLE_CALLBACK, params);
}
コード例 #13
0
void ImapActivityFactory::BuildPreferencesWatch(ActivityBuilder& ab, const MojObject& accountId, MojInt64 rev)
{
	MojErr err;

	ab.SetName( GetPreferencesWatchName(accountId) );
	ab.SetDescription("IMAP account preferences watch");
	ab.SetPersist(true);
	ab.SetForeground(true);

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, PREFS_WATCH_NAME, accountId);
	ab.SetMetadata(metadata);

	MojDbQuery trigger;
	err = trigger.from(ImapAccountAdapter::SCHEMA);
	ErrorToException(err);
	err = trigger.where(ImapAccountAdapter::ACCOUNT_ID, MojDbQuery::OpEq, accountId);
	ErrorToException(err);
	err = trigger.where(ImapAccountAdapter::CONFIG_REV, MojDbQuery::OpGreaterThan, rev);
	ErrorToException(err);
	ab.SetDatabaseWatchTrigger(trigger);

	MojObject params;
	err = params.put("accountId", accountId);
	ErrorToException(err);

	ab.SetCallback(PREFS_WATCH_CALLBACK, params);
}
コード例 #14
0
void NetworkStatusMonitor::CreateActivity()
{
	ActivityBuilder ab;

	static MojInt64 uniqueId = 0;

	string serviceName = m_busClient.GetServiceName();

	// FIXME
	if(serviceName.empty()) {
		throw MailException("no service name", __FILE__, __LINE__);
	}

	MojString name;
	MojErr err = name.format("%s network status check - %lld", serviceName.c_str(), ++uniqueId);
	ErrorToException(err);

	ab.SetName(name.data());
	ab.SetDescription("Monitors network status");
	ab.SetExplicit(false);
	ab.SetPersist(false);
	ab.SetForeground(true);
	ab.SetRequiresInternet(true);

	m_activity = Activity::PrepareNewActivity(ab, true, true);
	m_activity->SetSlots(m_activityUpdateSlot, m_activityErrorSlot);
	m_activity->Create(m_busClient);
}
コード例 #15
0
void ScheduleRetryCommand::ScheduleRetry()
{
	CommandTraceFunction();

	ImapActivityFactory factory;
	ActivityBuilder ab;

	// Get current retry interval from account
	EmailAccount::RetryStatus retryStatus = m_client.GetAccount().GetRetry();

	int interval = retryStatus.GetInterval();

	if(interval < INITIAL_RETRY_SECONDS) {
		interval = INITIAL_RETRY_SECONDS;
	} else if(interval < SECOND_RETRY_SECONDS) {
		interval = SECOND_RETRY_SECONDS;
	} else if(interval >= MAX_RETRY_SECONDS) {
		interval = MAX_RETRY_SECONDS;
	} else {
		// TODO: only update this on actual retry?
		interval *= RETRY_MULTIPLIER;
	}

	// Update account just in case it wasn't within the limit
	retryStatus.SetInterval(interval);
	retryStatus.SetCount(retryStatus.GetCount() + 1);
	m_client.GetAccount().SetRetry(retryStatus);

	factory.BuildSyncRetry(ab, m_client.GetAccountId(), m_folderId, interval, m_reason);

	MojErr err;
	MojObject payload;
	err = payload.put("activity", ab.GetActivityObject());
	ErrorToException(err);
	err = payload.put("start", true);
	ErrorToException(err);
	err = payload.put("replace", true);

	MojLogInfo(m_log, "scheduling retry in %.1f minutes for account %s", float(interval) / 60, m_client.GetAccountIdString().c_str());

	m_client.SendRequest(m_scheduleRetrySlot, "com.palm.activitymanager", "create", payload);
}
コード例 #16
0
void SmtpAccountEnableCommand::CreateSmtpConfigWatch()
{
	SmtpActivityFactory factory;
	ActivityBuilder ab;

	factory.BuildSmtpConfigWatch(ab, m_client.GetAccountId(), m_accountRev);

	// Create payload
	MojObject payload;
	MojErr err;

	err = payload.put("activity", ab.GetActivityObject());
	ErrorToException(err);
	err = payload.put("start", true);
	ErrorToException(err);
	err = payload.put("replace", true);
	ErrorToException(err);

	m_client.SendRequest(m_createSmtpConfigWatchSlot, "com.palm.activitymanager", "create", payload);
}
コード例 #17
0
void UpdateAccountCommand::UpdatePreferencesWatchActivity(MojInt64 rev)
{
	CommandTraceFunction();

	ImapActivityFactory factory;
	ActivityBuilder ab;

	MojLogInfo(m_log, "account %s preferences watch updated; rev=%lld", AsJsonString(m_accountId).c_str(), rev);

	if(rev > 0) {
		factory.BuildPreferencesWatch(ab, m_accountId, rev);

		m_activitySet->ReplaceActivity(ab.GetName(), ab.GetActivityObject());
	} else {
		MojLogCritical(m_log, "unknown preferences rev (couldn't load account?); can't create watch");

		m_activitySet->SetEndAction(Activity::EndAction_Complete);
	}

	m_activitySet->EndActivities(m_endActivitiesSlot);
}
コード例 #18
0
void ImapActivityFactory::BuildIdleWakeup(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId, int seconds)
{
	ab.SetName( GetIdleWakeupName(accountId, folderId) );
	ab.SetDescription("Wakes up idle connection");
	ab.SetExplicit(false); // goes away after a cancel
	ab.SetPersist(false);
	ab.SetForeground(true); // must run immediately
	ab.SetPowerOptions(false, true);

	// Wakeup
	ab.SetStartDelay(seconds);
}
コード例 #19
0
void SmtpActivityFactory::BuildSmtpConfigWatch(ActivityBuilder& ab, const MojObject& accountId, MojInt64 rev)
{
	MojErr err;

	MojString name;
	err = name.format(ACCOUNT_WATCH_ACTIVITY_FMT, AsJsonString(accountId).c_str());
	ErrorToException(err);

	// description of watch
	MojString desc;
	err = desc.format("Watches SMTP config on account %s", AsJsonString(accountId).c_str());
	ErrorToException(err);

	// activity to setup watch
	ab.SetName(name);
	ab.SetDescription(desc.data());
	ab.SetPersist(true);
	ab.SetExplicit(true);
	ab.SetRequiresInternet(false); // trigger even if we don't have a network connection
	ab.SetImmediate(true, ActivityBuilder::PRIORITY_LOW);

	// setup trigger
	// NOTE: how to trigger only on SMTP config change?
	MojDbQuery trigger;
	err = trigger.from("com.palm.mail.account:1");
	ErrorToException(err);
	err = trigger.where("accountId", MojDbQuery::OpEq, accountId);
	ErrorToException(err);

	if (rev > 0) {
		trigger.where("_revSmtp", MojDbQuery::OpGreaterThan, rev);
	}
	ab.SetDatabaseWatchTrigger(trigger);

	MojObject params;
	err = params.put("accountId", accountId);
	ErrorToException(err);

	ab.SetCallback(ACCOUNT_UPDATED_BUS_METHOD, params);
	ab.SetMetadata(params);
}
コード例 #20
0
void ImapActivityFactory::BuildSyncRetry(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId, int seconds, const std::string& reason)
{
	MojErr err;

	ab.SetName( GetSyncRetryName(accountId, folderId) );

	MojString desc;
	err = desc.format("Retry sync after %d seconds", seconds);
	ErrorToException(err);

	ab.SetDescription(desc.data());
	ab.SetExplicit(true);
	ab.SetPersist(true);
	ab.SetImmediate(true, "low");
	SetNetworkRequirements(ab, seconds <= 5 * 60);

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, SYNC_RETRY_NAME, accountId, folderId);
	ab.SetMetadata(metadata);

	// Wakeup
	ab.SetSyncInterval(seconds, 0);

	// Callback
	MojObject params;
	err = params.put("accountId", accountId);
	ErrorToException(err);
	err = params.put("folderId", folderId);
	ErrorToException(err);

	MojObject retry;
	if(!reason.empty()) {
		err = retry.putString("reason", reason.c_str());
		ErrorToException(err);
	}

	err = retry.put("interval", seconds);
	ErrorToException(err);

	err = params.put("retry", retry);
	ErrorToException(err);

	ab.SetCallback(SYNC_RETRY_CALLBACK, params);
}
コード例 #21
0
void ActivityBuilderFactory::BuildFolderRetrySync(ActivityBuilder &builder, const MojObject& folderId, int currInterval)
{
	// activity to setup watch
	MojString name;
	GetFolderRetrySyncActivityName(name, folderId);

	// description of watch
	MojString desc;
	GetFolderRetrySyncActivityDesc(desc, folderId);

	// retry interval in seconds
	int nextRetryInterval = GetNextRetryIntervalMins(currInterval);
	int intervalSecs = MinsToSecs(nextRetryInterval);

	builder.SetName(name.data());
	builder.SetDescription(desc.data());
	builder.SetPersist(true);
	builder.SetExplicit(true);
	builder.SetRequiresInternet(false);
	builder.SetImmediate(true, "low");
	builder.SetSyncInterval(0, intervalSecs);

	// setup parameters (to be sent when trigger is called)
	MojObject params;
	MojErr err = params.put(PopAccountAdapter::ACCOUNT_ID, m_accountId);
	ErrorToException(err);
	err = params.put("folderId", folderId);
	ErrorToException(err);
	err = params.put("lastRetryInterval", nextRetryInterval);
	ErrorToException(err);
	builder.SetCallback(FOLDER_RETRY_SYNC_CALLBACK, params);

	// put accountId in metadata
	MojObject metadata;
	err = metadata.put("accountId", m_accountId);
	ErrorToException(err);
	builder.SetMetadata(metadata);
}
コード例 #22
0
void ActivityBuilderFactory::BuildSentEmailsWatch(ActivityBuilder& builder, const MojObject& outboxFolderId, const MojObject& sentFolderId)
{
	// activity to setup watch
	MojString name;
	GetSentEmailsWatchActivityName(name);

	// description of watch
	MojString desc;
	GetSentEmailsWatchActivityDesc(desc);

	builder.SetName(name.data());
	builder.SetDescription(desc.data());
	builder.SetPersist(true);
	builder.SetExplicit(true);
	builder.SetForeground(true);

	// setup trigger
	MojDbQuery trigger;
	MojErr err = trigger.from(EmailSchema::Kind::EMAIL);
	ErrorToException(err);
	err = trigger.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, outboxFolderId);
	ErrorToException(err);
	err = trigger.where("sendStatus.sent", MojDbQuery::OpEq, true);
	ErrorToException(err);
	builder.SetDatabaseWatchTrigger(trigger);

	// setup parameters (to be sent when trigger is called)
	MojObject params;
	err = params.put(PopFolderAdapter::ACCOUNT_ID, m_accountId);
	ErrorToException(err);
	err = params.put(PopFolderAdapter::OUTBOX_FOLDER_ID, outboxFolderId);
	ErrorToException(err);
	err = params.put(PopFolderAdapter::SENT_FOLDER_ID, sentFolderId);
	ErrorToException(err);
	builder.SetCallback(SENT_EMAILS_WATCH_CALLBACK, params);

	// put accountId in metadata
	MojObject metadata;
	err = metadata.put("accountId", m_accountId);
	ErrorToException(err);
	builder.SetMetadata(metadata);
}
コード例 #23
0
// This is used if we don't have any other activity to get network status from
void ImapActivityFactory::BuildConnect(ActivityBuilder& ab, const MojObject& accountId, MojUInt64 uniqueId)
{
	MojString name;
	MojErr err = name.format("%s - %lld", CONNECT_NAME, uniqueId);
	ErrorToException(err);

	ab.SetName( FormatName(name.data(), accountId) );
	ab.SetDescription("Activity for connecting to server");
	ab.SetExplicit(false);
	ab.SetPersist(false);
	ab.SetForeground(true);
	ab.SetRequiresInternet(false);
}
コード例 #24
0
void ImapActivityFactory::BuildFolderWatch(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId, MojInt64 rev)
{
	MojErr err;
	MojDbQuery query;

	ab.SetName( GetFolderWatchName(accountId, folderId) );
	ab.SetDescription("Watches for updates to emails");
	ab.SetExplicit(true);
	ab.SetPersist(true);
	SetNetworkRequirements(ab, true);
	ab.SetImmediate(true, "low");

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, FOLDER_WATCH_NAME, accountId, folderId);
	ab.SetMetadata(metadata);

	// Query
	err = query.from(ImapEmailAdapter::IMAP_EMAIL_KIND);
	ErrorToException(err);
	err = query.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, folderId);
	ErrorToException(err);
	err = query.where(ImapEmailAdapter::UPSYNC_REV, MojDbQuery::OpGreaterThan, rev);
	ErrorToException(err);
	err = query.includeDeleted(true);
	ErrorToException(err);

	ab.SetDatabaseWatchTrigger(query);

	// Callback
	MojObject callbackParams;
	err = callbackParams.put("accountId", accountId);
	ErrorToException(err);
	err = callbackParams.put("folderId", folderId);
	ErrorToException(err);

	ab.SetCallback(FOLDER_WATCH_CALLBACK, callbackParams);
}
コード例 #25
0
void ImapActivityFactory::BuildDraftsWatch(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId, MojInt64 rev)
{
	MojErr err;

	ab.SetName( GetDraftsWatchName(accountId, folderId) );
	ab.SetDescription("Watches for updates to draft emails");
	ab.SetPersist(true);
	ab.SetExplicit(true);
	ab.SetForeground(true);

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, DRAFTS_WATCH_NAME, accountId, folderId);
	ab.SetMetadata(metadata);

	MojDbQuery query;

	err = query.from(EmailSchema::Kind::EMAIL);
	ErrorToException(err);
	err = query.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, folderId);
	ErrorToException(err);

	MojString editedDraftFlag;
	editedDraftFlag.format("%s.%s", EmailSchema::FLAGS, EmailSchema::Flags::EDITEDDRAFT);
	err = query.where(editedDraftFlag.data(), MojDbQuery::OpEq, true);
	ErrorToException(err);

	ab.SetDatabaseWatchTrigger(query);

	// Callback
	MojObject callbackParams;
	err = callbackParams.put("accountId", accountId);
	ErrorToException(err);
	err = callbackParams.put("folderId", accountId);
	ErrorToException(err);

	ab.SetCallback(DRAFTS_WATCH_CALLBACK, callbackParams);
}
コード例 #26
0
void ImapActivityFactory::BuildOutboxWatch(ActivityBuilder& ab, const MojObject& accountId, const MojObject& folderId, MojInt64 rev)
{
	MojErr err;

	ab.SetName( GetOutboxWatchName(accountId, folderId) );
	ab.SetDescription("Watches for sent emails in outbox");
	ab.SetPersist(true);
	ab.SetExplicit(true);
	ab.SetForeground(true);

	// Metadata
	MojObject metadata;
	SetMetadata(metadata, OUTBOX_WATCH_NAME, accountId, folderId);
	ab.SetMetadata(metadata);

	MojDbQuery query;

	err = query.from(EmailSchema::Kind::EMAIL);
	ErrorToException(err);
	err = query.where(EmailSchema::FOLDER_ID, MojDbQuery::OpEq, folderId);
	ErrorToException(err);

	// sendStatus.sent
	MojString sentProp;
	sentProp.format("%s.%s",EmailSchema::SEND_STATUS, EmailSchema::SendStatus::SENT);
	err = query.where(sentProp.data(), MojDbQuery::OpEq, true);
	ErrorToException(err);

	ab.SetDatabaseWatchTrigger(query);

	// Callback
	MojObject callbackParams;
	err = callbackParams.put("accountId", accountId);
	ErrorToException(err);

	ab.SetCallback(OUTBOX_WATCH_CALLBACK, callbackParams);
}
コード例 #27
0
void SmtpSyncOutboxCommand::CheckNetworkConnectivity()
{
	try {

		if (m_networkStatus->IsKnown()) {
			if (m_networkStatus->IsConnected()) {
				MojLogInfo(m_log, "CheckNetworkActivity: is connected, moving on");
				GetAccount();
				return;
			} else {
				MojLogInfo(m_log, "CheckNetworkActivity: is not connected, erroring out");
				// Note that this account error explicitly doesn't delay the retry, on the assumption
				// that the next activity will be blocked until the network is available.
				m_error.errorCode = MailError::NO_NETWORK;
				m_error.errorOnAccount = true;
				m_error.errorOnEmail = false;
				m_error.internalError = "No network available for outbox sync";
				m_error.errorText = "";

				CompleteAndUpdateActivities();
				return;
			}
		} else {
			MojLogInfo(m_log, "CheckNetworkActivity: state unknown, starting new activity");
			MojLogInfo(m_log, "OutboxSyncer creating new network activity");
			ActivityBuilder ab;
			MojString name;
			MojErr err = name.format("SMTP Internal Outbox Sync Network Activity for account %s", AsJsonString(m_accountId).c_str());
			ErrorToException(err);
			ab.SetName(name);
			ab.SetDescription("Activity representing SMTP Outbox Sync Network Monitor");
			ab.SetForeground(true);
			ab.SetRequiresInternet(false);
			ab.SetImmediate(true, ActivityBuilder::PRIORITY_LOW);
			m_networkActivity = Activity::PrepareNewActivity(ab);
			m_networkActivity->SetSlots(m_networkActivityUpdatedSlot, m_networkActivityErrorSlot);
			m_networkActivity->Create(m_client);
		}

	} catch (std::exception & e) {
		HandleException(e, __func__);
	} catch (...) {
		HandleException(__func__);
	}
}
コード例 #28
0
ファイル: ImapSession.cpp プロジェクト: Garfonso/app-services
void ImapSession::CommandComplete(Command* command)
{
	m_commandManager->CommandComplete(command);

	if(m_reconnectRequested && m_state == State_OkToSync && m_commandManager->GetActiveCommandCount() == 0 && m_commandManager->GetPendingCommandCount() > 0) {
		// If requested (and no active commands), disconnect from the server after finishing this command
		MojLogInfo(m_log, "disconnecting and reconnecting to server");

		Logout();
	} else if(m_state == State_OkToSync && m_commandManager->GetPendingCommandCount() == 0
			&& m_commandManager->GetActiveCommandCount() == 0) {
		MojLogInfo(m_log, "no commands active or pending");

		// Either disconnect or run IDLE command
		// TODO also check account settings

		if(IsValidId(m_folderId) && IsPushEnabled(m_folderId)) {
			m_shouldPush = CheckNetworkHealthForPush();
		} else {
			m_shouldPush = false;
		}

		if(m_shouldPush) {
			//MojLogInfo(m_log, "running idle command for folderId %s", AsJsonString(m_folderId).c_str());
			if(m_account->IsYahoo()) {
				m_idleCommand.reset(new IdleYahooCommand(*this, m_folderId));
				m_idleMode = IdleMode_YahooPush;
			} else {
				m_idleCommand.reset(new IdleCommand(*this, m_folderId));
				m_idleMode = IdleMode_IDLE;
			}

			// Create activity to maintain idle.
			// If the device is rebooted or IMAP crashes, the callback will restart idle.
			// The activity will get cancelled if the connection goes into retry mode.
			if(true) {
				ImapActivityFactory factory;
				ActivityBuilder ab;

				factory.BuildStartIdle(ab, m_client->GetAccountId(), m_folderId);

				// Create new activity only if one doesn't already exist
				if(GetActivitySet()->FindActivityByName(ab.GetName()).get() == NULL) {
					ActivityPtr activity = Activity::PrepareNewActivity(ab, true, true);
					activity->SetName(ab.GetName());

					activity->SetEndAction(Activity::EndAction_Complete);
					activity->SetEndOrder(Activity::EndOrder_Last);
					GetActivitySet()->AddActivity(activity);

					// Start activity right away
					activity->Create(*m_client);
				}
			}

			m_idleStartTime = 0;

			SetState(State_PreparingToIdle);
			m_commandManager->RunCommand(m_idleCommand);
		} else if(GetNoopIdleTimeout() > 0) {
			// TODO: this code is currently disabled
			MojLogInfo(m_log, "running NOOP idle command");
			m_idleCommand.reset(new NoopIdleCommand(*this, m_folderId, GetNoopIdleTimeout()));

			m_idleMode = IdleMode_NOOP;
			m_idleStartTime = 0;

			// Reset flag
			m_recentUserInteraction = false;

			SetState(State_PreparingToIdle);
			m_commandManager->RunCommand(m_idleCommand);

		} else {
			if(IsPushRequested(m_folderId) && !m_shouldPush) {
				MojLogInfo(m_log, "setting up scheduled sync instead of push");

				// If we can't push, set up a scheduled sync
				ImapActivityFactory factory;
				ActivityBuilder ab;

				factory.BuildScheduledSync(ab, m_client->GetAccountId(), m_folderId, FALLBACK_SYNC_INTERVAL, false);

				GetActivitySet()->ReplaceActivity(ab.GetName(), ab.GetActivityObject());
			} else {
				MojLogInfo(m_log, "nothing left to do; disconnecting");
			}

			Logout();
		}
	} else if(m_state == State_Disconnecting && m_commandManager->GetActiveCommandCount() == 0) {
		Disconnected();
	}
}