void Feed::appendArticle(const Article& a) { if ( (a.keep() && Settings::doNotExpireImportantArticles()) || ( !usesExpiryByAge() || !isExpired(a) ) ) // if not expired { if (!d->articles.contains(a.guid())) { d->articles[a.guid()] = a; if (!a.isDeleted() && a.status() != Read) setUnread(unread()+1); } } }
bool Criterion::satisfiedBy(const Article &article) const { if (article.isNull()) { return false; } QVariant concreteSubject; switch (m_subject) { case Title: concreteSubject = QVariant(article.title()); break; case Description: concreteSubject = QVariant(article.description()); break; case Link: // ### Maybe use prettyUrl here? concreteSubject = QVariant(article.link().url()); break; case Status: concreteSubject = QVariant(article.status()); break; case KeepFlag: concreteSubject = QVariant(article.keep()); break; case Author: concreteSubject = QVariant(article.authorName()); default: break; } bool satisfied = false; const Predicate predicateType = static_cast<Predicate>(m_predicate & ~Negation); QString subjectType = QLatin1String(concreteSubject.typeName()); switch (predicateType) { case Contains: satisfied = concreteSubject.toString().indexOf(m_object.toString(), 0, Qt::CaseInsensitive) != -1; break; case Equals: if (subjectType == QLatin1String("int")) { satisfied = concreteSubject.toInt() == m_object.toInt(); } else { satisfied = concreteSubject.toString() == m_object.toString(); } break; case Matches: satisfied = QRegExp(m_object.toString()).indexIn(concreteSubject.toString()) != -1; break; default: qCDebug(AKREGATOR_LOG) << "Internal inconsistency; predicateType should never be Negation"; break; } if (m_predicate & Negation) { satisfied = !satisfied; } return satisfied; }
void Feed::appendArticles(const Syndication::FeedPtr feed) { d->setTotalCountDirty(); bool changed = false; const bool notify = useNotification() || Settings::useNotifications(); QList<ItemPtr> items = feed->items(); QList<ItemPtr>::ConstIterator it = items.constBegin(); QList<ItemPtr>::ConstIterator en = items.constEnd(); int nudge=0; QList<Article> deletedArticles = d->deletedArticles; for ( ; it != en; ++it) { if ( !d->articles.contains((*it)->id()) ) // article not in list { Article mya(*it, this); mya.offsetPubDate(nudge); nudge--; appendArticle(mya); d->addedArticlesNotify.append(mya); if (!mya.isDeleted() && !markImmediatelyAsRead()) mya.setStatus(New); else mya.setStatus(Read); if ( notify ) NotificationManager::self()->slotNotifyArticle( mya ); changed = true; } else // article is in list { // if the article's guid is no hash but an ID, we have to check if the article was updated. That's done by comparing the hash values. Article old = d->articles[(*it)->id()]; Article mya(*it, this); if (!mya.guidIsHash() && mya.hash() != old.hash() && !old.isDeleted()) { mya.setKeep(old.keep()); int oldstatus = old.status(); old.setStatus(Read); d->articles.remove(old.guid()); appendArticle(mya); mya.setStatus(oldstatus); d->updatedArticlesNotify.append(mya); changed = true; } else if (old.isDeleted()) deletedArticles.removeAll(mya); } } QList<Article>::ConstIterator dit = deletedArticles.constBegin(); QList<Article>::ConstIterator dtmp; QList<Article>::ConstIterator den = deletedArticles.constEnd(); // delete articles with delete flag set completely from archive, which aren't in the current feed source anymore while (dit != den) { dtmp = dit; ++dit; d->articles.remove((*dtmp).guid()); d->archive->deleteArticle((*dtmp).guid()); d->removedArticlesNotify.append( *dtmp ); changed = true; d->deletedArticles.removeAll(*dtmp); } if (changed) articlesModified(); }