Added support older RSS formats and ATOM. Moreover, message SQL updates are now done in transactions.
This commit is contained in:
parent
b4d60e01f1
commit
c04805a6f7
8 changed files with 104 additions and 15 deletions
|
@ -68,12 +68,12 @@ INSERT INTO Categories (id, parent_id, title, description, date_created, type) V
|
|||
-- !
|
||||
INSERT INTO Categories (id, parent_id, title, description, date_created, type) VALUES (2, -1, 'RSS Guard', 'News and updates on RSS Guard.', '2013-12-20T08:00:00-05:00', 0);
|
||||
-- !
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Linux Today', 'Linux Today - Linux News on Internet Time.', '2013-12-20T08:00:00-05:00', 1, 'UTF-8', 'http://feeds.feedburner.com/linuxtoday/linux?format=xml', 2);
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Linux Today', 'Linux Today - Linux News on Internet Time.', '2013-12-20T08:00:00-05:00', 1, 'UTF-8', 'http://feeds.feedburner.com/linuxtoday/linux?format=xml', 1);
|
||||
-- !
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('LinuxInsider', 'LinuxInsider: Linux News & Information from Around the World.', '2013-12-20T08:00:00-05:00', 1, 'UTF-8', 'http://www.linuxinsider.com/perl/syndication/rssfull.pl', 3);
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('LinuxInsider', 'LinuxInsider: Linux News & Information from Around the World.', '2013-12-20T08:00:00-05:00', 1, 'UTF-8', 'http://www.linuxinsider.com/perl/syndication/rssfull.pl', 2);
|
||||
-- !
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Recent Commits', 'Recent commits for RSS Guard project.', '2013-12-20T08:00:00-05:00', 2, 'UTF-8', 'https://github.com/martinrotter/rssguard/commits/master.atom', 4);
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Recent Commits', 'Recent commits for RSS Guard project.', '2013-12-20T08:00:00-05:00', 2, 'UTF-8', 'https://github.com/martinrotter/rssguard/commits/master.atom', 3);
|
||||
-- !
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Releases', 'Releases for RSS Guard.', '2013-12-20T08:00:00-05:00', 2, 'UTF-8', 'https://github.com/martinrotter/rssguard/releases.atom', 4);
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Releases', 'Releases for RSS Guard.', '2013-12-20T08:00:00-05:00', 2, 'UTF-8', 'https://github.com/martinrotter/rssguard/releases.atom', 3);
|
||||
-- !
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Author''s Activity', 'RSS Guard author public activity overview.', '2013-12-20T08:00:00-05:00', 2, 'UTF-8', 'https://github.com/martinrotter.atom', 4);
|
||||
INSERT INTO Feeds (title, description, date_created, category, encoding, url, type) VALUES ('Author''s Activity', 'RSS Guard author public activity overview.', '2013-12-20T08:00:00-05:00', 2, 'UTF-8', 'https://github.com/martinrotter.atom', 3);
|
|
@ -99,7 +99,7 @@ QSqlDatabase DatabaseFactory::initialize(const QString &connection_name) {
|
|||
|
||||
QStringList statements = QString(file_init.readAll()).split(APP_DB_INIT_SPLIT,
|
||||
QString::SkipEmptyParts);
|
||||
query_db.exec("BEGIN TRANSACTION");
|
||||
database.transaction();
|
||||
|
||||
foreach(const QString &statement, statements) {
|
||||
query_db.exec(statement);
|
||||
|
@ -110,7 +110,7 @@ QSqlDatabase DatabaseFactory::initialize(const QString &connection_name) {
|
|||
}
|
||||
}
|
||||
|
||||
query_db.exec("COMMIT");
|
||||
database.commit();
|
||||
qDebug("Database backend should be ready now.");
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -255,10 +255,9 @@ void FeedsModel::loadFromDatabase() {
|
|||
FeedsModelFeed::Type type = static_cast<FeedsModelFeed::Type>(query_feeds.value(FDS_DB_TYPE_INDEX).toInt());
|
||||
|
||||
switch (type) {
|
||||
case FeedsModelFeed::StandardAtom:
|
||||
case FeedsModelFeed::StandardAtom10:
|
||||
case FeedsModelFeed::StandardRdf:
|
||||
case FeedsModelFeed::StandardRss0X:
|
||||
case FeedsModelFeed::StandardRss1X:
|
||||
case FeedsModelFeed::StandardRss2X: {
|
||||
FeedAssignmentItem pair;
|
||||
pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt();
|
||||
|
|
|
@ -50,7 +50,7 @@ void FeedsModelFeed::setType(const Type &type) {
|
|||
|
||||
QString FeedsModelFeed::typeToString(FeedsModelFeed::Type type) {
|
||||
switch (type) {
|
||||
case StandardAtom:
|
||||
case StandardAtom10:
|
||||
return QObject::tr("ATOM 1.0");
|
||||
|
||||
case StandardRdf:
|
||||
|
|
|
@ -12,10 +12,9 @@ class FeedsModelFeed : public FeedsModelRootItem {
|
|||
// NOTE: This is equivalent to attribute Feeds(type).
|
||||
enum Type {
|
||||
StandardRss0X = 0,
|
||||
StandardRss1X = 1,
|
||||
StandardRss2X = 2,
|
||||
StandardRdf = 3,
|
||||
StandardAtom = 4
|
||||
StandardRss2X = 1,
|
||||
StandardRdf = 2,
|
||||
StandardAtom10 = 3
|
||||
};
|
||||
|
||||
// Constructors and destructors.
|
||||
|
@ -44,6 +43,7 @@ class FeedsModelFeed : public FeedsModelRootItem {
|
|||
Type type() const;
|
||||
void setType(const Type &type);
|
||||
|
||||
// Converts particular feed type to string.
|
||||
static QString typeToString(Type type);
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -182,6 +182,7 @@ void FeedsModelStandardFeed::update() {
|
|||
QList<Message> messages;
|
||||
|
||||
switch (type()) {
|
||||
case FeedsModelFeed::StandardRss0X:
|
||||
case FeedsModelFeed::StandardRss2X:
|
||||
messages = ParsingFactory::parseAsRSS20(formatted_feed_contents);
|
||||
break;
|
||||
|
@ -190,6 +191,9 @@ void FeedsModelStandardFeed::update() {
|
|||
messages = ParsingFactory::parseAsRDF(formatted_feed_contents);
|
||||
break;
|
||||
|
||||
case FeedsModelFeed::StandardAtom10:
|
||||
messages = ParsingFactory::parseAsATOM10(formatted_feed_contents);
|
||||
|
||||
// TODO: Add support for other standard formats.
|
||||
|
||||
default:
|
||||
|
@ -214,6 +218,13 @@ void FeedsModelStandardFeed::updateMessages(const QList<Message> &messages) {
|
|||
"(feed, title, url, author, date_created, contents) "
|
||||
"VALUES (:feed, :title, :url, :author, :date_created, :contents);");
|
||||
|
||||
if (!database.transaction()) {
|
||||
database.rollback();
|
||||
|
||||
qDebug("Transaction start for message downloader failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (const Message &message, messages) {
|
||||
query_select.bindValue(":feed", feed_id);
|
||||
query_select.bindValue(":title", message.m_title);
|
||||
|
@ -248,4 +259,10 @@ void FeedsModelStandardFeed::updateMessages(const QList<Message> &messages) {
|
|||
// online feed.
|
||||
}
|
||||
}
|
||||
|
||||
if (!database.commit()) {
|
||||
database.rollback();
|
||||
|
||||
qDebug("Transaction commit for message downloader failed.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,6 +145,11 @@ QVariant MessagesModel::data(const QModelIndex &index, int role) const {
|
|||
return TextFactory::parseDateTime(QSqlTableModel::data(index,
|
||||
role).toString()).toString(Qt::DefaultLocaleShortDate);
|
||||
}
|
||||
else if (index_column == MSG_DB_AUTHOR_INDEX) {
|
||||
QString author_name = QSqlTableModel::data(index, role).toString();
|
||||
|
||||
return author_name.isEmpty() ? "-" : author_name;
|
||||
}
|
||||
else if (index_column != MSG_DB_IMPORTANT_INDEX &&
|
||||
index_column != MSG_DB_READ_INDEX) {
|
||||
return QSqlTableModel::data(index, role);
|
||||
|
|
|
@ -11,7 +11,75 @@ ParsingFactory::ParsingFactory() {
|
|||
|
||||
QList<Message> ParsingFactory::parseAsATOM10(const QString &data) {
|
||||
// TODO: Implement this.
|
||||
return QList<Message>();
|
||||
|
||||
QList<Message> messages;
|
||||
QDomDocument xml_file;
|
||||
QDateTime current_time = QDateTime::currentDateTime();
|
||||
|
||||
xml_file.setContent(data, true);
|
||||
|
||||
// Pull out all messages.
|
||||
QDomNodeList messages_in_xml = xml_file.elementsByTagName("entry");
|
||||
|
||||
for (int i = 0; i < messages_in_xml.size(); i++) {
|
||||
QDomNode message_item = messages_in_xml.item(i);
|
||||
Message new_message;
|
||||
|
||||
// Deal with titles & descriptions.
|
||||
QString elem_title = message_item.namedItem("title").toElement().text().simplified();
|
||||
QString elem_summary = message_item.namedItem("summary").toElement().text();
|
||||
|
||||
if (elem_summary.isEmpty()) {
|
||||
elem_summary = message_item.namedItem("content").toElement().text();
|
||||
}
|
||||
|
||||
// Now we obtained maximum of informations for title & description.
|
||||
if (elem_title.isEmpty()) {
|
||||
if (elem_summary.isEmpty()) {
|
||||
// BOTH title and description are empty, skip this message.
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// Title is empty but description is not.
|
||||
new_message.m_title = TextFactory::stripTags(elem_summary.simplified());
|
||||
new_message.m_contents = elem_summary;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Title is not empty, description does not matter.
|
||||
new_message.m_title = TextFactory::stripTags(elem_title);
|
||||
new_message.m_contents = elem_summary;
|
||||
}
|
||||
|
||||
// Deal with link.
|
||||
QDomNodeList elem_links = message_item.toElement().elementsByTagName("link");
|
||||
|
||||
for (int i = 0; i < elem_links.size(); i++) {
|
||||
QDomNode elem_link = elem_links.at(i);
|
||||
|
||||
if (elem_link.attributes().namedItem("rel").toAttr().value() == "alternate") {
|
||||
new_message.m_url = elem_link.attributes().namedItem("href").toAttr().value();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with authors.
|
||||
new_message.m_author = TextFactory::escapeHtml(message_item.namedItem("author").namedItem("name").toElement().text());
|
||||
|
||||
// Deal with creation date.
|
||||
new_message.m_created = TextFactory::parseDateTime(message_item.namedItem("updated").toElement().text());
|
||||
new_message.m_createdFromFeed = !new_message.m_created.isNull();
|
||||
|
||||
if (!new_message.m_createdFromFeed) {
|
||||
// Date was NOT obtained from the feed,
|
||||
// set current date as creation date for the message.
|
||||
new_message.m_created = current_time;
|
||||
}
|
||||
|
||||
messages.append(new_message);
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
QList<Message> ParsingFactory::parseAsRDF(const QString &data) {
|
||||
|
|
Loading…
Add table
Reference in a new issue