Changeset - ab8a950661d4
[Not reviewed]
0 5 0
Jan Kaluza - 10 years ago 2015-11-25 21:52:29
jkaluza@redhat.com
Fix various small Slack bugs
5 files changed with 89 insertions and 24 deletions:
0 comments (0 inline, 0 general)
spectrum/src/frontends/slack/SlackAPI.cpp
Show inline comments
 
@@ -251,24 +251,30 @@ void SlackAPI::getSlackUserInfo(HTTPRequest *req, bool ok, rapidjson::Document &
 
		LOG4CXX_INFO(logger, info.id << " " << info.name);
 
	}
 

	
 
	return;
 
}
 

	
 
std::string &SlackAPI::SlackObjectToPlainText(std::string &object, bool isChannel) {
 
std::string SlackAPI::SlackObjectToPlainText(const std::string &object, bool isChannel, bool returnName) {
 
	std::string ret = object;
 
	if (isChannel) {
 
		if (object[0] == '<') {
 
			object = object.substr(2, object.size() - 3);
 
		if (ret[0] == '<') {
 
			ret = ret.substr(2, ret.size() - 3);
 
		}
 
	} else {
 
		if (object[0] == '<') {
 
			object = object.substr(1, object.size() - 2);
 
			object = object.substr(object.find("|") + 1);
 
		if (ret[0] == '<') {
 
			ret = ret.substr(1, ret.size() - 2);
 
			if (returnName) {
 
				ret = ret.substr(0, ret.find("|"));
 
			}
 
			else {
 
				ret = ret.substr(ret.find("|") + 1);
 
			}
 
		}
 
	}
 

	
 
	return object;
 
	return ret;
 
}
 

	
 

	
 

	
 
}
spectrum/src/frontends/slack/SlackAPI.h
Show inline comments
 
@@ -81,13 +81,13 @@ class SlackAPI : public HTTPRequestQueue {
 

	
 
		void sendMessage(const std::string &from, const std::string &to, const std::string &text);
 

	
 
		static void getSlackChannelInfo(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data, std::map<std::string, SlackChannelInfo> &channels);
 
		static void getSlackImInfo(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data, std::map<std::string, SlackImInfo> &ims);
 
		static void getSlackUserInfo(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data, std::map<std::string, SlackUserInfo> &users);
 
		static std::string &SlackObjectToPlainText(std::string &object, bool isChannel = false);
 
		static std::string SlackObjectToPlainText(const std::string &object, bool isChannel = false, bool returnName = false);
 

	
 
	private:
 
		void handleSendMessage(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data);
 

	
 
	private:
 
		Component *m_component;
spectrum/src/frontends/slack/SlackSession.cpp
Show inline comments
 
@@ -45,13 +45,13 @@ DEFINE_LOGGER(logger, "SlackSession");
 
SlackSession::SlackSession(Component *component, StorageBackend *storageBackend, UserInfo uinfo) : m_uinfo(uinfo) {
 
	m_component = component;
 
	m_storageBackend = storageBackend;
 

	
 
	m_rtm = new SlackRTM(component, storageBackend, uinfo);
 
	m_rtm->onRTMStarted.connect(boost::bind(&SlackSession::handleRTMStarted, this));
 
	m_rtm->onMessageReceived.connect(boost::bind(&SlackSession::handleMessageReceived, this, _1, _2, _3));
 
	m_rtm->onMessageReceived.connect(boost::bind(&SlackSession::handleMessageReceived, this, _1, _2, _3, false));
 

	
 
}
 

	
 
SlackSession::~SlackSession() {
 
	delete m_rtm;
 
}
 
@@ -67,13 +67,13 @@ void SlackSession::sendMessage(boost::shared_ptr<Swift::Message> message) {
 
		return;
 
	}
 

	
 
	m_rtm->getAPI()->sendMessage(message->getFrom().getResource(), channel, message->getBody());
 
}
 

	
 
void SlackSession::handleMessageReceived(const std::string &channel, const std::string &user, const std::string &message) {
 
void SlackSession::handleMessageReceived(const std::string &channel, const std::string &user, const std::string &message, bool quiet) {
 
	if (m_ownerChannel != channel) {
 
		std::string to = m_channel2jid[channel];
 
		if (!to.empty()) {
 
			boost::shared_ptr<Swift::Message> msg(new Swift::Message());
 
			msg->setType(Swift::Message::Groupchat);
 
			msg->setTo(to);
 
@@ -93,15 +93,15 @@ void SlackSession::handleMessageReceived(const std::string &channel, const std::
 
	}
 

	
 
	if (args[1] == "join.room") {
 
		// .spectrum2 join.room BotName #room irc.freenode.net channel
 
		if (args.size() == 6) {
 
			std::string &name = args[2];
 
			std::string &legacyRoom = SlackAPI::SlackObjectToPlainText(args[3], true);
 
			std::string &legacyServer = SlackAPI::SlackObjectToPlainText(args[4]);
 
			std::string &slackChannel = SlackAPI::SlackObjectToPlainText(args[5], true);
 
			std::string legacyRoom = SlackAPI::SlackObjectToPlainText(args[3], true);
 
			std::string legacyServer = SlackAPI::SlackObjectToPlainText(args[4]);
 
			std::string slackChannel = SlackAPI::SlackObjectToPlainText(args[5], true);
 

	
 
			m_uinfo.uin = name;
 
			m_storageBackend->setUser(m_uinfo);
 

	
 
			std::string to = legacyRoom + "%" + legacyServer + "@" + m_component->getJID().toString();
 
			m_jid2channel[to] = slackChannel;
 
@@ -119,22 +119,78 @@ void SlackSession::handleMessageReceived(const std::string &channel, const std::
 
			presence->setFrom(Swift::JID("", m_uinfo.jid, "default"));
 
			presence->setTo(Swift::JID(to + "/" + name));
 
			presence->setType(Swift::Presence::Available);
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
 
			m_component->getFrontend()->onPresenceReceived(presence);
 

	
 
			std::string msg;
 
			msg += "Spectrum 2 is now joining the room. To leave the room later to disable transporting, you can use `.spectrum2 leave.room #SlackChannel`.";
 
			if (!quiet) {
 
				std::string msg;
 
				msg += "Spectrum 2 is now joining the room. To leave the room later to disable transporting, you can use `.spectrum2 leave.room #" + SlackAPI::SlackObjectToPlainText(args[5], true, true) + "`.";
 
				m_rtm->sendMessage(m_ownerChannel, msg);
 
			}
 
		}
 
	}
 
	else if (args[1] == "leave.room") {
 
		// .spectrum2 leave.room channel
 
		if (args.size() == 3) {
 
			std::string slackChannel = SlackAPI::SlackObjectToPlainText(args[2], true);
 
			std::string to = m_channel2jid[slackChannel];
 
			if (to.empty()) {
 
				m_rtm->sendMessage(m_ownerChannel, "Spectrum 2 is not configured to transport this Slack channel.");
 
				return;
 
			}
 

	
 
			std::string rooms = "";
 
			int type = (int) TYPE_STRING;
 
			m_storageBackend->getUserSetting(m_uinfo.id, "rooms", type, rooms);
 

	
 
			std::vector<std::string> commands;
 
			boost::split(commands, rooms, boost::is_any_of("\n"));
 
			rooms = "";
 

	
 
			BOOST_FOREACH(const std::string &command, commands) {
 
				if (command.size() > 5) {
 
					std::vector<std::string> args2;
 
					boost::split(args2, command, boost::is_any_of(" "));
 
					if (args2.size() == 6) {
 
						if (slackChannel != SlackAPI::SlackObjectToPlainText(args2[5], true)) {
 
							rooms += command + "\n";
 
						}
 
					}
 
				}
 
			}
 

	
 
			m_storageBackend->updateUserSetting(m_uinfo.id, "rooms", rooms);
 

	
 
			Swift::Presence::ref presence = Swift::Presence::create();
 
			presence->setFrom(Swift::JID("", m_uinfo.jid, "default"));
 
			presence->setTo(Swift::JID(to + "/" + m_uinfo.uin));
 
			presence->setType(Swift::Presence::Unavailable);
 
			presence->addPayload(boost::shared_ptr<Swift::Payload>(new Swift::MUCPayload()));
 
			m_component->getFrontend()->onPresenceReceived(presence);
 
		}
 
	}
 
	else if (args[1] == "list.rooms") {
 
		// .spectrum2 list.rooms
 
		if (args.size() == 2) {
 
			std::string rooms = "";
 
			int type = (int) TYPE_STRING;
 
			m_storageBackend->getUserSetting(m_uinfo.id, "rooms", type, rooms);
 

	
 
			std::string msg = "Spectrum 2 is configured for following channels:\\n";
 
			msg += "```" + rooms  + "```";
 
			m_rtm->sendMessage(m_ownerChannel, msg);
 
		}
 
	}
 
	else if (args[1] == "help") {
 
		std::string msg;
 
		msg =  "Following commands are supported:\\n";
 
		msg += "```.spectrum2 help``` Shows this help message.\\n";
 
		msg += "```.spectrum2 join.room <3rdPartyBotName> <#3rdPartyRoom> <3rdPartyServer> <#SlackChannel>``` Starts transport between 3rd-party room and Slack channel.";
 
		msg += "```.spectrum2 leave.room <#SlackChannel>``` Leaves the 3rd-party room connected with the given Slack channel.";
 
		msg += "```.spectrum2 list.rooms``` List all the transported rooms.";
 
		m_rtm->sendMessage(m_ownerChannel, msg);
 
	}
 
	else {
 
		m_rtm->sendMessage(m_ownerChannel, "Unknown command. Use `.spectrum2 help` for help.");
 
	}
 
}
 
@@ -161,14 +217,16 @@ void SlackSession::handleImOpen(HTTPRequest *req, bool ok, rapidjson::Document &
 
	}
 
	else {
 
		std::vector<std::string> commands;
 
		boost::split(commands, rooms, boost::is_any_of("\n"));
 

	
 
		BOOST_FOREACH(const std::string &command, commands) {
 
			LOG4CXX_INFO(logger, m_uinfo.jid << ": Sending command from storage: " << command);
 
			handleMessageReceived(m_ownerChannel, "owner", command);
 
			if (command.size() > 5) {
 
				LOG4CXX_INFO(logger, m_uinfo.jid << ": Sending command from storage: " << command);
 
				handleMessageReceived(m_ownerChannel, "owner", command, true);
 
			}
 
		}
 
	}
 
}
 

	
 
void SlackSession::handleRTMStarted() {
 
	std::string ownerId;
spectrum/src/frontends/slack/SlackSession.h
Show inline comments
 
@@ -48,13 +48,13 @@ class SlackSession {
 
		boost::signal<void (const std::string &user)> onInstallationDone;
 

	
 
		void sendMessage(boost::shared_ptr<Swift::Message> message);
 

	
 
	private:
 
		void handleRTMStarted();
 
		void handleMessageReceived(const std::string &channel, const std::string &user, const std::string &message);
 
		void handleMessageReceived(const std::string &channel, const std::string &user, const std::string &message, bool quiet);
 
		void handleImOpen(HTTPRequest *req, bool ok, rapidjson::Document &resp, const std::string &data);
 

	
 
	private:
 
		Component *m_component;
 
		StorageBackend *m_storageBackend;
 
		UserInfo m_uinfo;
src/SQLite3Backend.cpp
Show inline comments
 
@@ -117,13 +117,13 @@ bool SQLite3Backend::connect() {
 

	
 
	sqlite3_busy_timeout(m_db, 1500);
 

	
 
	if (createDatabase() == false)
 
		return false;
 

	
 
	PREP_STMT(m_setUser, "INSERT OR REPLACE INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, DATETIME('NOW'), ?)");
 
	PREP_STMT(m_setUser, "INSERT OR REPLACE INTO " + m_prefix + "users (id, jid, uin, password, language, encoding, last_login, vip) VALUES ((SELECT id FROM " + m_prefix + "users WHERE jid = ?), ?, ?, ?, ?, ?, DATETIME('NOW'), ?)");
 
	PREP_STMT(m_getUser, "SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=?");
 

	
 
	PREP_STMT(m_removeUser, "DELETE FROM " + m_prefix + "users WHERE id=?");
 
	PREP_STMT(m_removeUserBuddies, "DELETE FROM " + m_prefix + "buddies WHERE user_id=?");
 
	PREP_STMT(m_removeUserSettings, "DELETE FROM " + m_prefix + "users_settings WHERE user_id=?");
 
	PREP_STMT(m_removeUserBuddiesSettings, "DELETE FROM " + m_prefix + "buddies_settings WHERE user_id=?");
 
@@ -221,17 +221,18 @@ bool SQLite3Backend::exec(const std::string &query) {
 
	return true;
 
}
 

	
 
void SQLite3Backend::setUser(const UserInfo &user) {
 
	sqlite3_reset(m_setUser);
 
	sqlite3_bind_text(m_setUser, 1, user.jid.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 2, user.uin.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 3, user.password.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 4, user.language.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 5, user.encoding.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_int (m_setUser, 6, user.vip);
 
	sqlite3_bind_text(m_setUser, 2, user.jid.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 3, user.uin.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 4, user.password.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 5, user.language.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_text(m_setUser, 6, user.encoding.c_str(), -1, SQLITE_STATIC);
 
	sqlite3_bind_int (m_setUser, 7, user.vip);
 

	
 
	if(sqlite3_step(m_setUser) != SQLITE_DONE) {
 
		LOG4CXX_ERROR(logger, "setUser query"<< (sqlite3_errmsg(m_db) == NULL ? "" : sqlite3_errmsg(m_db)));
 
	}
 
}
 

	
0 comments (0 inline, 0 general)