Possible to add Tiny Tiny RSS account now.

This commit is contained in:
Martin Rotter 2015-12-03 09:19:59 +01:00
parent 2d54dac6fa
commit b61814db88
14 changed files with 240 additions and 37 deletions

View File

@ -21,6 +21,14 @@ CREATE TABLE IF NOT EXISTS Accounts (
-- !
INSERT INTO Accounts (type) VALUES ('std-rss');
-- !
CREATE TABLE IF NOT EXISTS TtRssAccounts (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password TEXT,
url TEXT NOT NULL,
FOREIGN KEY (id) REFERENCES Accounts (id)
);
DROP TABLE IF EXISTS Categories;
-- !
CREATE TABLE IF NOT EXISTS Categories (

View File

@ -15,6 +15,15 @@ CREATE TABLE IF NOT EXISTS Accounts (
-- !
INSERT INTO Accounts (type) VALUES ('std-rss');
-- !
CREATE TABLE IF NOT EXISTS TtRssAccounts (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password TEXT,
url TEXT NOT NULL,
FOREIGN KEY (id) REFERENCES Accounts (id)
);
-- !
DROP TABLE IF EXISTS Categories;
-- !
CREATE TABLE IF NOT EXISTS Categories (

View File

@ -7,4 +7,13 @@ INSERT INTO Accounts (type) VALUES ('std-rss');
-- !
DROP TABLE IF EXISTS FeedsData;
-- !
CREATE TABLE IF NOT EXISTS TtRssAccounts (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password TEXT,
url TEXT NOT NULL,
FOREIGN KEY (id) REFERENCES Accounts (id)
);
-- !
UPDATE Information SET inf_value = '4' WHERE inf_key = 'schema_version';

View File

@ -7,4 +7,13 @@ INSERT INTO Accounts (type) VALUES ('std-rss');
-- !
DROP TABLE IF EXISTS FeedsData;
-- !
CREATE TABLE IF NOT EXISTS TtRssAccounts (
id INTEGER PRIMARY KEY,
username TEXT NOT NULL,
password TEXT,
url TEXT NOT NULL,
FOREIGN KEY (id) REFERENCES Accounts (id)
);
-- !
UPDATE Information SET inf_value = '4' WHERE inf_key = 'schema_version';

View File

@ -81,6 +81,7 @@ void MessagesModel::loadMessages(RootItem *item) {
}
else {
if (!item->getParentServiceRoot()->loadMessagesForItem(item, this)) {
setFilter("true != true");
qWarning("Loading of messages from item '%s' failed.", qPrintable(item->title()));
qApp->showGuiMessage(tr("Loading of messages from item '%s' failed.").arg(item->title()),
tr("Loading of messages failed, maybe messages could not be downloaded."),

View File

@ -203,7 +203,9 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
copy_contents.exec(QString("ATTACH DATABASE '%1' AS 'storage';").arg(file_database.databaseName()));
// Copy all stuff.
QStringList tables; tables << QSL("Information") << QSL("Categories") << QSL("Feeds") << QSL("FeedsData") << QSL("Messages");
// WARNING: All tables belong here.
QStringList tables; tables << QSL("Information") << QSL("Categories") << QSL("Feeds") <<
QSL("FeedsData") << QSL("Messages") << QSL("Accounts") << QSL("TtRssAccounts");
foreach (const QString &table, tables) {
copy_contents.exec(QString("INSERT INTO main.%1 SELECT * FROM storage.%1;").arg(table));
@ -468,8 +470,9 @@ void DatabaseFactory::sqliteSaveMemoryDatabase() {
copy_contents.exec(QString(QSL("ATTACH DATABASE '%1' AS 'storage';")).arg(file_database.databaseName()));
// Copy all stuff.
// WARNING: All tables belong here.
QStringList tables; tables << QSL("Categories") << QSL("Feeds") << QSL("FeedsData") <<
QSL("Messages");
QSL("Messages") << QSL("Accounts") << QSL("TtRssAccounts");
foreach (const QString &table, tables) {
copy_contents.exec(QString(QSL("DELETE FROM storage.%1;")).arg(table));

View File

@ -23,4 +23,3 @@ Category::Category(RootItem *parent) : RootItem(parent) {
Category::~Category() {
}

View File

@ -50,12 +50,23 @@ class Feed : public RootItem {
explicit Feed(RootItem *parent = NULL);
virtual ~Feed();
/////////////////////////////////////////
// /* Members to override.
/////////////////////////////////////////
// Performs synchronous update and returns number of newly updated messages.
// NOTE: This should COMPLETELY download ALL messages from online source
// into locale "Messages" table, INCLUDING contents (or excerpts) of those
// messages.
virtual int update() = 0;
// Get ALL undeleted messages from this feed in one single list.
virtual QList<Message> undeletedMessages() const = 0;
/////////////////////////////////////////
// Members to override. */
/////////////////////////////////////////
inline int autoUpdateInitialInterval() const {
return m_autoUpdateInitialInterval;
}

View File

@ -31,6 +31,10 @@ class RecycleBin : public RootItem {
QVariant data(int column, int role) const;
public slots:
/////////////////////////////////////////
// /* Members to override.
/////////////////////////////////////////
// Empties the bin - removes all messages from it (does not remove
// them from DB, just permanently hide them, so that they are not
// re-downloaded).
@ -38,6 +42,10 @@ class RecycleBin : public RootItem {
// Performs complete restoration of all messages contained in the bin
virtual bool restore() = 0;
/////////////////////////////////////////
// Members to override. */
/////////////////////////////////////////
};
#endif // RECYCLEBIN_H

View File

@ -32,6 +32,10 @@ class ServiceEntryPoint {
// Constructors.
virtual ~ServiceEntryPoint();
/////////////////////////////////////////
// /* Members to override.
/////////////////////////////////////////
// Creates new service root item, which is ready to be added
// into the model. This method can for example display
// some kind of first-time configuration dialog inside itself
@ -68,6 +72,10 @@ class ServiceEntryPoint {
// Icon of the service.
virtual QIcon icon() = 0;
/////////////////////////////////////////
// Members to override. */
/////////////////////////////////////////
};
#endif // SERVICE_H

View File

@ -40,6 +40,10 @@ class ServiceRoot : public RootItem {
explicit ServiceRoot(RootItem *parent = NULL);
virtual ~ServiceRoot();
/////////////////////////////////////////
// /* Members to override.
/////////////////////////////////////////
// Returns list of specific actions for "Add new item" main window menu.
// So typical list of returned actions could look like:
// a) Add new feed
@ -127,6 +131,10 @@ class ServiceRoot : public RootItem {
// Selected item is naturally recycle bin.
virtual bool onAfterMessagesRestoredFromBin(RootItem *selected_item, QList<int> message_db_ids) = 0;
/////////////////////////////////////////
// Members to override. */
/////////////////////////////////////////
// Obvious methods to wrap signals.
void itemChanged(QList<RootItem*> items);
void requestReloadMessageList(bool mark_selected_messages_read);
@ -135,6 +143,7 @@ class ServiceRoot : public RootItem {
void requestItemReassignment(RootItem *item, RootItem *new_parent);
void requestItemRemoval(RootItem *item);
// Account ID corresponds with DB attribute Accounts (id).
int accountId() const;
void setAccountId(int account_id);

View File

@ -135,10 +135,16 @@ void FormEditAccount::performTest() {
void FormEditAccount::onClickedOk() {
if (m_editableRoot == NULL) {
// We want to confirm newly created account.
// So save new account into DB, setup its properties.
m_editableRoot = new TtRssServiceRoot(false);
}
else {
// We want to edit existing account.
}
m_editableRoot->network()->setUrl(m_ui->m_txtUrl->lineEdit()->text());
m_editableRoot->network()->setUsername(m_ui->m_txtUsername->lineEdit()->text());
m_editableRoot->network()->setPassword(m_ui->m_txtPassword->lineEdit()->text());
m_editableRoot->saveToDatabase();
accept();
}
void FormEditAccount::onClickedCancel() {

View File

@ -20,17 +20,34 @@
#include "miscellaneous/application.h"
#include "miscellaneous/settings.h"
#include "services/tt-rss/ttrssserviceentrypoint.h"
#include "core/feedsmodel.h"
#include "services/tt-rss/network/ttrssnetworkfactory.h"
#include <QSqlQuery>
#include <QSqlError>
TtRssServiceRoot::TtRssServiceRoot(RootItem *parent) : ServiceRoot(parent) {
// TODO: nadpis se bude měnit podle nastavení uživatelského
// jména a serveru tohoto ttrss učtu
setTitle(qApp->system()->getUsername() + "@ttrss");
TtRssServiceRoot::TtRssServiceRoot(bool load_from_db, RootItem *parent)
: ServiceRoot(parent), m_network(new TtRssNetworkFactory) {
setIcon(TtRssServiceEntryPoint().icon());
setCreationDate(QDateTime::currentDateTime());
if (load_from_db) {
loadFromDatabase();
}
}
TtRssServiceRoot::~TtRssServiceRoot() {
if (m_network != NULL) {
delete m_network;
}
}
void TtRssServiceRoot::start() {
}
void TtRssServiceRoot::stop() {
}
QString TtRssServiceRoot::code() {
@ -41,6 +58,10 @@ bool TtRssServiceRoot::editViaGui() {
return false;
}
bool TtRssServiceRoot::deleteViaGui() {
return false;
}
bool TtRssServiceRoot::canBeEdited() {
return true;
}
@ -68,3 +89,103 @@ QVariant TtRssServiceRoot::data(int column, int role) const {
return ServiceRoot::data(column, role);
}
}
QList<QAction*> TtRssServiceRoot::addItemMenu() {
return QList<QAction*>();
}
RecycleBin *TtRssServiceRoot::recycleBin() {
return NULL;
}
bool TtRssServiceRoot::loadMessagesForItem(RootItem *item, QSqlTableModel *model) {
return false;
}
QList<QAction*> TtRssServiceRoot::serviceMenu() {
return QList<QAction*>();
}
bool TtRssServiceRoot::onBeforeSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, RootItem::ReadStatus read) {
return false;
}
bool TtRssServiceRoot::onAfterSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, RootItem::ReadStatus read) {
return false;
}
bool TtRssServiceRoot::onBeforeSwitchMessageImportance(RootItem *selected_item, QList<QPair<int, RootItem::Importance> > changes) {
return false;
}
bool TtRssServiceRoot::onAfterSwitchMessageImportance(RootItem *selected_item, QList<QPair<int, RootItem::Importance> > changes) {
return false;
}
bool TtRssServiceRoot::onBeforeMessagesDelete(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
bool TtRssServiceRoot::onAfterMessagesDelete(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
bool TtRssServiceRoot::onBeforeMessagesRestoredFromBin(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
bool TtRssServiceRoot::onAfterMessagesRestoredFromBin(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
TtRssNetworkFactory *TtRssServiceRoot::network() const {
return m_network;
}
void TtRssServiceRoot::saveToDatabase() {
if (accountId() != NO_PARENT_CATEGORY) {
// We are overwritting previously saved data.
// TODO: todo
updateTitle();
itemChanged(QList<RootItem*>() << this);
}
else {
// We are probably saving newly added account.
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
QSqlQuery query(database);
// First obtain the ID, which can be assigned to this new account.
if (!query.exec("SELECT max(id) FROM Accounts;") || !query.next()) {
return;
}
int id_to_assing = query.value(0).toInt() + 1;
bool saved = query.exec(QString("INSERT INTO Accounts (id, type) VALUES (%1, '%2');").arg(QString::number(id_to_assing),
SERVICE_CODE_TT_RSS)) &&
query.exec(QString("INSERT INTO TtRssAccounts (id, username, password, url) VALUES (%1, '%2', '%3', '%4');").arg(QString::number(id_to_assing),
network()->username(),
network()->password(),
network()->url()));
if (saved) {
setAccountId(id_to_assing);
updateTitle();
}
}
}
void TtRssServiceRoot::loadFromDatabase() {
// Account ID is set, load connection data from DB.
}
void TtRssServiceRoot::updateTitle() {
QString host = QUrl(m_network->url()).host();
if (host.isEmpty()) {
host = m_network->url();
}
setTitle(m_network->username() + QL1S("@") + host);
}

View File

@ -23,53 +23,55 @@
#include <QCoreApplication>
class FeedsModel;
class TtRssNetworkFactory;
class TtRssServiceRoot : public ServiceRoot {
Q_OBJECT
public:
explicit TtRssServiceRoot(RootItem *parent = NULL);
explicit TtRssServiceRoot(bool load_from_db, RootItem *parent = NULL);
virtual ~TtRssServiceRoot();
void start();
void stop();
QString code();
bool canBeEdited();
bool canBeDeleted();
bool editViaGui();
bool deleteViaGui();
QVariant data(int column, int role) const;
bool onBeforeSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read) {
return false;
}
QList<QAction *> addItemMenu();
QList<QAction *> serviceMenu();
bool onAfterSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read) {
return false;
}
RecycleBin *recycleBin();
bool onBeforeSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes) {
return false;
}
bool loadMessagesForItem(RootItem *item, QSqlTableModel *model);
bool onAfterSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes) {
return false;
}
bool onBeforeSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read);
bool onAfterSetMessagesRead(RootItem *selected_item, QList<int> message_db_ids, ReadStatus read);
bool onBeforeMessagesDelete(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
bool onBeforeSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes);
bool onAfterSwitchMessageImportance(RootItem *selected_item, QList<QPair<int,RootItem::Importance> > changes);
bool onAfterMessagesDelete(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
bool onBeforeMessagesDelete(RootItem *selected_item, QList<int> message_db_ids);
bool onAfterMessagesDelete(RootItem *selected_item, QList<int> message_db_ids);
bool onBeforeMessagesRestoredFromBin(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
bool onBeforeMessagesRestoredFromBin(RootItem *selected_item, QList<int> message_db_ids);
bool onAfterMessagesRestoredFromBin(RootItem *selected_item, QList<int> message_db_ids);
bool onAfterMessagesRestoredFromBin(RootItem *selected_item, QList<int> message_db_ids) {
return false;
}
TtRssNetworkFactory *network() const;
void saveToDatabase();
void loadFromDatabase();
private:
void updateTitle();
TtRssNetworkFactory *m_network;
};
#endif // TTRSSSERVICEROOT_H