123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /*
- * Copyright 2009 Andrew Stromme <astromme@chatonka.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2, 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 General Public License for more details
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- #include "xmlreaders.h"
- #include "note.h"
- #include "request.h"
- #include "session.h"
- #include "session_p.h"
- #include "task.h"
- #include "task_p.h"
- #include <QCoreApplication>
- #include <KDebug>
- #include <QNetworkReply>
- struct TempProps {
- QString name;
- RTM::TaskSeriesId seriesId;
- RTM::ListId listId;
- QHash<RTM::NoteId, RTM::Note> notes;
- QList<RTM::Tag> tags;
- };
- RTM::TasksReader::TasksReader(RTM::Request* r, RTM::Session* s)
- : QXmlStreamReader(r),
- session(s),
- request(r)
- {
- Q_ASSERT(r);
- Q_ASSERT(s);
- request->open(QIODevice::ReadOnly);
- request->seek(0);
- }
- QList< RTM::List* > RTM::TasksReader::readLists() const {
- return changedLists;
- }
- QList< RTM::Task* > RTM::TasksReader::readTasks() const {
- return changedTasks;
- }
- QDateTime RTM::TasksReader::parseDateTime(const QString& datetime)
- {
- QDateTime offsetTime = QDateTime::fromString(datetime, Qt::ISODate);
- return localizedTime(offsetTime);
- }
- QDateTime RTM::TasksReader::localizedTime(const QDateTime& datetime)
- {
- QDateTime dt = QDateTime(datetime.date(), datetime.time(), Qt::LocalTime);
- KTimeZone utc = KSystemTimeZones::zone("UTC");
- KTimeZone rtm = session->d->timezone;
- //kDebug() << datetime << dt << utc.convert(rtm, dt);
- return utc.convert(rtm, dt);
- }
- bool RTM::TasksReader::read() {
- while (!atEnd()) {
- readNext();
- // if (isEndElement())
- // Do I need to close/save my task?
- if (isStartElement()) {
- if (name().toString() == "rsp")
- readResponse();
- else
- readUnknownElement();
- }
- }
- foreach(RTM::Task* task, changedTasks)
- emit session->taskChanged(task);
- foreach(RTM::List* list, changedLists)
- emit session->listChanged(list);
- if (changedTasks.count() > 0)
- emit session->tasksChanged();
- if (changedLists.count() > 0)
- emit session->listsChanged();
- this->device()->close();
- return true; // !error();
- }
- bool RTM::TasksReader::readResponse() {
- if (attributes().value("stat") != "ok") {
- //TODO: Provide more meaningful error
- return false;
- }
- while (!atEnd()) {
- readNext();
- if (isEndElement()) {
- return true;
- }
-
- if (isStartElement()) {
- if (name() == "tasks")
- readTasksHeader();
- else if (name() == "lists")
- readListsHeader();
- else if (name() == "transaction")
- readTransaction();
- else
- readUnknownElement();
- }
- }
- kDebug() << "Reached the end of readResponse() where we shouldn't have" << name().toString() << text().toString();
- kDebug() << "Attributes:";
-
- for(int i=0; i < attributes().count(); i++)
- { kDebug() << attributes().at(i).name().toString() << attributes().at(i).value().toString(); }
- return false;
- }
- void RTM::TasksReader::readTransaction() {
- // If we're not using a getList method we need to jump to the correct spot
- QStringList splitMethod = request->method().split('.');
- readNext();
-
- if (splitMethod.at(splitMethod.count() - 2) == "tasks")
- readTasksHeader();
- else if (splitMethod.at(splitMethod.count() - 2) == "lists")
- readListsHeader();
- else {
- kDebug() << "Unknown Method: " << splitMethod.join(".");
- readUnknownElement();
- }
- }
- void RTM::TasksReader::readUnknownElement() {
- kDebug() << "Unknown Element: " << tokenString() << name().toString() << text().toString();
- kDebug() << "Attributes:";
-
- for(int i=0; i < attributes().count(); i++)
- { kDebug() << attributes().at(i).name().toString() << attributes().at(i).value().toString(); }
-
- while(!atEnd()) {
- readNext();
-
- if (isEndElement())
- break;
-
- if (isStartElement())
- readUnknownElement();
- }
- }
- void RTM::TasksReader::readFilter(RTM::List* list) {
- list->setFilter(readElementText());
- kDebug() << "Filter for list: " << list->name() << " is " << list->filter();
- // while (!atEnd()) {
- // readNext();
- // if (isEndElement())
- // return;
- // if (isStartElement())
- // readUnknownElement();
- // }
- }
- void RTM::TasksReader::readList() {
- RTM::List *list = session->listFromId(attributes().value("id").toString().toULong());
- if (!list)
- list = session->newBlankList(attributes().value("id").toString().toULong());
- list->setId(attributes().value("id").toString().toULong());
- list->setName(attributes().value("name").toString());
- list->setSmart(attributes().value("smart").toString() == "1" ? true : false);
-
- changedLists.append(list);
-
- while (!atEnd()) {
- readNext();
- if (isEndElement()) {
- session->d->lists.insert(list->id(), list);
- if (list->isSmart())
- session->d->populateSmartList(list);
- return;
- }
- if (isStartElement()) {
- if (name() == "filter")
- readFilter(list);
- else
- readUnknownElement();
- }
- }
- }
- void RTM::TasksReader::readListsHeader() {
- while (!atEnd()) {
- readNext();
- if (isEndElement()) {
- return;
- }
-
- if (isStartElement()) {
- if (name() == "list")
- readList();
- else
- readUnknownElement();
- }
- }
- }
- void RTM::TasksReader::readNotes(TempProps* props) {
- //kDebug() << "Notes not supported yet";
- if (isEndElement())
- return;
- while (!atEnd()) {
- readNext();
- if ((isEndElement()) && (name().toString() == "notes"))
- break;
- if (isEndElement())
- continue; // end of a note
- if ((isStartElement()) && (name().toString() == "note")) {
- RTM::Note note(attributes().value("id").toString().toULong(), attributes().value("title").toString(), readElementText());
- props->notes.insert(note.id(), note);
- }
- else
- readUnknownElement();
- }
- }
- void RTM::TasksReader::readParticipants(TempProps* props) {
- Q_UNUSED(props);
- //kDebug() << "Participants not supported yet";
- if (isEndElement())
- return;
- while (!atEnd()) {
- readNext();
- if ((isEndElement()) && (name().toString() == "participants"))
- break;
- }
- }
- void RTM::TasksReader::readTags(TempProps* props) {
- if (isEndElement())
- return;
- while (!atEnd()) {
- readNext();
- if ((isEndElement()) && (name().toString() == "tags"))
- break;
- if (isEndElement())
- continue;
- if ((isStartElement()) && (name().toString() == "tag"))
- props->tags.append(readElementText());
- else
- readUnknownElement();
- }
- }
- void RTM::TasksReader::readTask(TempProps *props) {
- RTM::Task *task = session->taskFromId(attributes().value("id").toString().toLongLong());
- if (!task)
- task = session->newBlankTask(attributes().value("id").toString().toLongLong());
- task->d->name = props->name;
- task->d->seriesId = props->seriesId;
- task->d->listId = props->listId;
- task->d->notes = props->notes;
- task->d->tags = props->tags;
-
- RTM::List *list = session->listFromId(props->listId);
- if (!list)
- list = session->newBlankList(props->listId);
- changedTasks.append(task);
- changedLists.append(list);
- // Grab ID
- task->d->taskId = attributes().value("id").toString().toULong();
- // Grab Priority
- if (attributes().value("priority") == "N")
- task->d->priority = 4;
- else
- task->d->priority = attributes().value("priority").toString().toInt();
- // Grab Due Date/Time
- task->d->due = parseDateTime(attributes().value("due").toString());
- // if (attributes().value("has_due_time") == "0") BUG: FIXME: Re-Implement time support
- // Grab Estimate
- task->d->estimate = attributes().value("estimate").toString();
- // Grab Completed/Deleted
- task->d->completed = parseDateTime(attributes().value("completed").toString());
- task->d->deleted = parseDateTime(attributes().value("deleted").toString());
- // TODO:: Grab Postponed
- // TODO: Parse rest of fields
- //kDebug() << "Adding Task: " << task->id() << " to list " << list->id() << "(" << list << ")";
- list->tasks.insert(task->id(), task);
- session->d->tasks.insert(task->id(), task);
- while (!atEnd()) {
- readNext();
- if (isEndElement())
- break;
- if (isStartElement())
- { kDebug() << "readTask().readNext(): " << name().toString(); }
- }
- }
- void RTM::TasksReader::readTaskSeries(RTM::ListId listId) {
-
- TempProps props;
- props.name = attributes().value("name").toString();
- props.seriesId = attributes().value("id").toString().toULong();
- props.listId = listId;
- while(!atEnd()) {
- readNext();
-
- if ((isEndElement()) && (name().toString() == "taskseries")) {
- break;
- }
- if (isEndElement()) {
- kDebug() << "Error in readTaskSeries() with end element: " << name().toString();
- break;
- }
-
- if (isStartElement()) {
- if (name().toString() == "tags")
- readTags(&props);
- else if (name().toString() == "participants")
- readParticipants(&props);
- else if (name().toString() == "notes")
- readNotes(&props);
- else if (name().toString() == "task")
- readTask(&props);
- else
- readUnknownElement();
- }
- }
-
- }
- void RTM::TasksReader::readTasksHeader() {
- while (!atEnd()) {
- readNext();
- if (isEndElement()) {
- return;
- }
- if (isStartElement()) {
- if (name() == "list")
- readTasksList();
- else
- readUnknownElement();
- }
- }
- }
- void RTM::TasksReader::readTasksList() {
- RTM::ListId currentListId = attributes().value("id").toString().toULong();
- while(!atEnd()) {
- readNext();
- if ((isEndElement()) && (name() == "list")) {
- break;
- }
- if (isEndElement()) {
- //Error in readTasksList() with end element: name()
- break;
- }
-
- if (isStartElement()) {
- if (name() == "taskseries")
- readTaskSeries(currentListId);
- else
- readUnknownElement();
- }
- }
- }
|