From 6bd72c67896a20041556519548650590553f47c9 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Tue, 20 Apr 2010 09:43:31 +0000 Subject: Add XEP-0203 (Delay) support. Puts delay warnings in the chat log. Not optional yet. diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index 793233e..abd346a 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -6,10 +6,14 @@ #include "Swift/Controllers/Chat/ChatControllerBase.h" +#include + #include #include +#include #include "Swiften/Client/StanzaChannel.h" +#include "Swiften/Elements/Delay.h" #include "Swiften/Base/foreach.h" #include "Swift/Controllers/UIInterfaces/ChatWindow.h" #include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h" @@ -69,6 +73,12 @@ void ChatControllerBase::handleSendMessageRequest(const String &body) { label = boost::optional(chatWindow_->getSelectedSecurityLabel()); } preSendMessageRequest(message); + //FIXME: optional + bool useSwiftDelay = true; + if (useSwiftDelay) { + boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + message->addPayload(boost::shared_ptr(new Delay(now, selfJID_))); + } stanzaChannel_->sendMessage(message); postSendMessage(message->getBody()); } @@ -121,6 +131,13 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr m return; } showChatWindow(); + boost::shared_ptr delayPayload = message->getPayload(); + if (delayPayload) { + boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + std::ostringstream s; + s << "The following message took " << (now - delayPayload->getStamp()).total_milliseconds() << " milliseconds to be delivered."; + chatWindow_->addSystemMessage(String(s.str())); + } boost::shared_ptr label = message->getPayload(); boost::optional maybeLabel = label ? boost::optional(*label) : boost::optional(); JID from = message->getFrom(); diff --git a/Swiften/Elements/ChatState.h b/Swiften/Elements/ChatState.h index a6b4d9b..8dcf77c 100644 --- a/Swiften/Elements/ChatState.h +++ b/Swiften/Elements/ChatState.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ diff --git a/Swiften/Elements/Delay.h b/Swiften/Elements/Delay.h new file mode 100644 index 0000000..f59d729 --- /dev/null +++ b/Swiften/Elements/Delay.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include +#include + +#include "Swiften/Elements/Payload.h" +#include "Swiften/JID/JID.h" + +namespace Swift { + class Delay : public Payload { + public: + Delay() {}; + Delay(const boost::posix_time::ptime& time, const JID& from) : time_(time), from_(from) {}; + + const boost::posix_time::ptime& getStamp() const {return time_;}; + void setStamp(const boost::posix_time::ptime& time) {time_ = time;}; + + const boost::optional& getFrom() const {return from_;}; + void setFrom(const JID& from) {from_ = from;}; + + private: + boost::posix_time::ptime time_; + boost::optional from_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/ChatStateParser.cpp b/Swiften/Parser/PayloadParsers/ChatStateParser.cpp index ef1f930..db205dd 100644 --- a/Swiften/Parser/PayloadParsers/ChatStateParser.cpp +++ b/Swiften/Parser/PayloadParsers/ChatStateParser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ diff --git a/Swiften/Parser/PayloadParsers/ChatStateParser.h b/Swiften/Parser/PayloadParsers/ChatStateParser.h index 4ca2f4d..2ae4e43 100644 --- a/Swiften/Parser/PayloadParsers/ChatStateParser.h +++ b/Swiften/Parser/PayloadParsers/ChatStateParser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ diff --git a/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h b/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h index a2eff2f..27d3c51 100644 --- a/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h +++ b/Swiften/Parser/PayloadParsers/ChatStateParserFactory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Remko Tronçon + * Copyright (c) 2010 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ diff --git a/Swiften/Parser/PayloadParsers/DelayParser.cpp b/Swiften/Parser/PayloadParsers/DelayParser.cpp new file mode 100644 index 0000000..a416ac1 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/DelayParser.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Parser/PayloadParsers/DelayParser.h" + +#include +#include + +#include + +namespace Swift { + +DelayParser::DelayParser() : level_(0) { +} + +boost::posix_time::ptime DelayParser::dateFromString(const String& string) { + boost::posix_time::time_input_facet* facet = new boost::posix_time::time_input_facet("%Y-%m-%d %H:%M:%S%F%Q"); + boost::posix_time::ptime result(boost::posix_time::not_a_date_time); + std::locale dateLocale(std::locale::classic(), facet); + std::istringstream stream(string.getUTF8String()); + stream.imbue(dateLocale); + stream >> result; + return result; +} + +void DelayParser::handleStartElement(const String& /*element*/, const String& /*ns*/, const AttributeMap& attributes) { + if (level_ == 0) { + boost::posix_time::ptime stamp = dateFromString(attributes.getAttribute("stamp")); + getPayloadInternal()->setStamp(stamp); + if (!attributes.getAttribute("from").isEmpty()) { + std::cout << attributes.getAttribute("from"); + String from = attributes.getAttribute("from"); + getPayloadInternal()->setFrom(JID(from)); + } + } + ++level_; +} + +void DelayParser::handleEndElement(const String&, const String&) { + --level_; +} + +void DelayParser::handleCharacterData(const String&) { + +} + +} diff --git a/Swiften/Parser/PayloadParsers/DelayParser.h b/Swiften/Parser/PayloadParsers/DelayParser.h new file mode 100644 index 0000000..ce92dc2 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/DelayParser.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include "Swiften/Elements/Delay.h" +#include "Swiften/Parser/GenericPayloadParser.h" + +namespace Swift { + class DelayParser : public GenericPayloadParser { + public: + DelayParser(); + + virtual void handleStartElement(const String& element, const String&, const AttributeMap& attributes); + virtual void handleEndElement(const String& element, const String&); + virtual void handleCharacterData(const String& data); + + private: + boost::posix_time::ptime dateFromString(const String& string); + int level_; + }; +} diff --git a/Swiften/Parser/PayloadParsers/DelayParserFactory.h b/Swiften/Parser/PayloadParsers/DelayParserFactory.h new file mode 100644 index 0000000..8b1f91e --- /dev/null +++ b/Swiften/Parser/PayloadParsers/DelayParserFactory.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include "Swiften/Parser/PayloadParserFactory.h" +#include "Swiften/Parser/PayloadParsers/DelayParser.h" + +namespace Swift { + class PayloadParserFactoryCollection; + + class DelayParserFactory : public PayloadParserFactory { + public: + DelayParserFactory() { + } + + virtual bool canParse(const String& /*element*/, const String& ns, const AttributeMap&) const { + return ns == "urn:xmpp:delay"; + } + + virtual PayloadParser* createPayloadParser() { + return new DelayParser(); + } + + }; +} diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp index b2fd54c..b0e4eb2 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp @@ -26,6 +26,7 @@ #include "Swiften/Parser/PayloadParsers/VCardParserFactory.h" #include "Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h" #include "Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h" +#include "Swiften/Parser/PayloadParsers/DelayParserFactory.h" using namespace boost; @@ -49,6 +50,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(shared_ptr(new VCardParserFactory())); factories_.push_back(shared_ptr(new PrivateStorageParserFactory(this))); factories_.push_back(shared_ptr(new ChatStateParserFactory())); + factories_.push_back(shared_ptr(new DelayParserFactory())); foreach(shared_ptr factory, factories_) { addFactory(factory.get()); } diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript index 7d93d8b..0d3aad2 100644 --- a/Swiften/Parser/SConscript +++ b/Swiften/Parser/SConscript @@ -35,6 +35,7 @@ sources = [ "PayloadParsers/StatusShowParser.cpp", "PayloadParsers/VCardParser.cpp", "PayloadParsers/VCardUpdateParser.cpp", + "PayloadParsers/DelayParser.cpp", "PlatformXMLParserFactory.cpp", "PresenceParser.cpp", "SerializingParser.cpp", diff --git a/Swiften/SConscript b/Swiften/SConscript index edc1885..a3426db 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -80,6 +80,7 @@ if env["SCONS_STAGE"] == "build" : "Serializer/PayloadSerializers/VCardUpdateSerializer.cpp", "Serializer/PayloadSerializers/StorageSerializer.cpp", "Serializer/PayloadSerializers/PrivateStorageSerializer.cpp", + "Serializer/PayloadSerializers/DelaySerializer.cpp", "Serializer/PresenceSerializer.cpp", "Serializer/StanzaSerializer.cpp", "Serializer/StreamFeaturesSerializer.cpp", diff --git a/Swiften/Serializer/PayloadSerializers/DelaySerializer.cpp b/Swiften/Serializer/PayloadSerializers/DelaySerializer.cpp new file mode 100644 index 0000000..041165f --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/DelaySerializer.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Serializer/PayloadSerializers/DelaySerializer.h" + +#include + +#include "Swiften/Serializer/XML/XMLElement.h" + +namespace Swift { + +DelaySerializer::DelaySerializer() : GenericPayloadSerializer() { +} + +String DelaySerializer::serializePayload(boost::shared_ptr delay) const { + XMLElement delayElement("delay", "urn:xmpp:delay"); + if (delay->getFrom()) { + delayElement.setAttribute("from", delay->getFrom()->toString()); + } + String stampString = String(boost::posix_time::to_iso_extended_string(delay->getStamp())); + stampString.replaceAll(',', "."); + stampString += "Z"; + delayElement.setAttribute("stamp", stampString); + return delayElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/DelaySerializer.h b/Swiften/Serializer/PayloadSerializers/DelaySerializer.h new file mode 100644 index 0000000..949b084 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/DelaySerializer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include "Swiften/Serializer/GenericPayloadSerializer.h" +#include "Swiften/Elements/Delay.h" + +namespace Swift { + class DelaySerializer : public GenericPayloadSerializer { + public: + DelaySerializer(); + + virtual String serializePayload(boost::shared_ptr) const; + }; +} + + diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp index 8c83c09..8dc9d86 100644 --- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp +++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp @@ -27,6 +27,7 @@ #include "Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h" #include "Swiften/Serializer/PayloadSerializers/StorageSerializer.h" #include "Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h" +#include "Swiften/Serializer/PayloadSerializers/DelaySerializer.h" namespace Swift { @@ -50,6 +51,7 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() { serializers_.push_back(new VCardUpdateSerializer()); serializers_.push_back(new RawXMLPayloadSerializer()); serializers_.push_back(new StorageSerializer()); + serializers_.push_back(new DelaySerializer()); serializers_.push_back(new PrivateStorageSerializer(this)); foreach(PayloadSerializer* serializer, serializers_) { addSerializer(serializer); -- cgit v0.10.2-6-g49f6