Changeset - bd9219797eb4
[Not reviewed]
0 8 0
Jan Kaluza - 10 years ago 2016-01-02 20:31:03
jkaluza@redhat.com
Fix crash in Twitter populateRoster with Swiften3; Commite spectru2_manager changes
8 files changed with 323 insertions and 61 deletions:
0 comments (0 inline, 0 general)
backends/twitter/TwitterPlugin.cpp
Show inline comments
 
@@ -85,6 +85,11 @@ TwitterPlugin::TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, Stora
 

	
 
	tweet_timer->start();
 
	message_timer->start();
 

	
 
#if HAVE_SWIFTEN_3
 
		cryptoProvider = boost::shared_ptr<Swift::CryptoProvider>(Swift::PlatformCryptoProvider::create());
 
#endif
 
	
 
	
 
	LOG4CXX_INFO(logger, "Starting the plugin.");
 
}
 
@@ -438,7 +443,7 @@ bool TwitterPlugin::setTwitterMode(const std::string user, int m)
 

	
 
	//int type;
 
	std::string s_m = std::string(1,m+'0');
 
	LOG4CXX_ERROR(logger, "Storing mode " << m <<" for user " << user)
 
	LOG4CXX_INFO(logger, "Storing mode " << m <<" for user " << user)
 
	storagebackend->updateUserSetting((long)info.id, MODE, s_m);
 
	return true;
 
}
spectrum_manager/src/CMakeLists.txt
Show inline comments
 
cmake_minimum_required(VERSION 2.6)
 
FILE(GLOB SRC *.cpp *.c)
 

	
 
ADD_EXECUTABLE(spectrum2_manager ${SRC} ../../libtransport/Config.cpp ../../libtransport/Util.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
 
ADD_EXECUTABLE(spectrum2_manager ${SRC})
 

	
 
ADD_DEPENDENCIES(spectrum2_manager pb)
 
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
 

	
 
target_link_libraries(spectrum2_manager ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
 
target_link_libraries(spectrum2_manager transport ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
 

	
 
if(APPLE)
 
target_link_libraries(spectrum2_manager ${APPLE_FRAMEWORKS})
 
target_link_libraries(spectrum2_manager transport ${APPLE_FRAMEWORKS})
 
endif()
 
INSTALL(TARGETS spectrum2_manager RUNTIME DESTINATION bin)
 

	
spectrum_manager/src/main.cpp
Show inline comments
 
@@ -142,7 +142,7 @@ int main(int argc, char **argv)
 
		return restart_instances(&config);
 
	}
 
	else if (command[0] == "server") {
 
		Server server(&config);
 
		Server server(&config, config_file);
 
		if (server.start() == false) {
 
			std::cerr << "Can't set up server handler.\n";
 
			return 1;
spectrum_manager/src/managerconfig.cpp
Show inline comments
 
@@ -33,8 +33,15 @@ bool ManagerConfig::load(const std::string &configfile, boost::program_options::
 
		("service.admin_password", value<std::string>()->default_value(""), "Administrator password.")
 
		("service.port", value<int>()->default_value(8081), "Web interface port.")
 
		("service.config_directory", value<std::string>()->default_value("/etc/spectrum2/transports/"), "Directory with spectrum2 configuration files. One .cfg file per one instance")
 
		("service.data_dir", value<std::string>()->default_value("/var/lib/spectrum2_manager"), "Directory to store Spectrum 2 manager data")
 
		("service.data_dir", value<std::string>()->default_value("/var/lib/spectrum2_manager/html"), "Directory to store Spectrum 2 manager data")
 
		("servers.server", value<std::vector<std::string> >()->multitoken(), "Server.")
 
		("database.type", value<std::string>()->default_value("none"), "Database type.")
 
		("database.database", value<std::string>()->default_value("/var/lib/spectrum2/$jid/database.sql"), "Database used to store data")
 
		("database.server", value<std::string>()->default_value("localhost"), "Database server.")
 
		("database.user", value<std::string>()->default_value(""), "Database user.")
 
		("database.password", value<std::string>()->default_value(""), "Database Password.")
 
		("database.port", value<int>()->default_value(0), "Database port.")
 
		("database.prefix", value<std::string>()->default_value(""), "Prefix of tables in database")
 
	;
 

	
 
	store(parse_config_file(ifs, opts), m_variables);
spectrum_manager/src/server.cpp
Show inline comments
 
@@ -51,7 +51,7 @@ static void _event_handler(struct mg_connection *nc, int ev, void *p) {
 
	static_cast<Server *>(nc->mgr->user_data)->event_handler(nc, ev, p);
 
}
 

	
 
Server::Server(ManagerConfig *config) {
 
Server::Server(ManagerConfig *config, const std::string &config_file) {
 
	srand((unsigned) time(0));
 
	m_config = config;
 
	m_user = CONFIG_STRING(m_config, "service.admin_username");
 
@@ -80,10 +80,29 @@ Server::Server(ManagerConfig *config) {
 
		footer.read(&m_footer[0], m_footer.size());
 
		footer.close();
 
	}
 

	
 
	m_storageCfg = new Config();
 
	m_storageCfg->load(config_file);
 

	
 
	std::string error;
 
	m_storage = StorageBackend::createBackend(m_storageCfg, error);
 
	if (m_storage == NULL) {
 
		std::cerr << "Error creating StorageBackend! " << error << "\n";
 
		std::cerr << "Registering new Spectrum 2 manager users won't work" << "\n";
 
	}
 
	else if (!m_storage->connect()) {
 
		delete m_storage;
 
		m_storage = NULL;
 
		std::cerr << "Can't connect to database!\n";
 
	}
 
}
 

	
 
Server::~Server() {
 
	mg_mgr_free(&m_mgr);
 
	if (m_storage) {
 
		delete m_storage;
 
	}
 
	delete m_storageCfg;
 
}
 

	
 
bool Server::start() {
 
@@ -95,7 +114,16 @@ bool Server::start() {
 
}
 

	
 
bool Server::check_password(const std::string &user, const std::string &password) {
 
	return (m_user == user && m_password == password);
 
	if (m_user == user && m_password == password) {
 
		return true;
 
	}
 

	
 
	UserInfo info;
 
	if (m_storage && m_storage->getUser(user, info) == true && info.password == password) {
 
		return true;
 
	}
 

	
 
	return false;
 
}
 

	
 
// Allocate new session object
 
@@ -192,6 +220,25 @@ void Server::print_html(struct mg_connection *conn, struct http_message *hm, con
 
			(int) html.size() + m_header.size() + m_footer.size(), m_header.c_str(), html.c_str(), m_footer.c_str());
 
}
 

	
 
std::string Server::send_command(const std::string &jid, const std::string &cmd) {
 
	Swift::SimpleEventLoop eventLoop;
 
	Swift::BoostNetworkFactories networkFactories(&eventLoop);
 

	
 
	ask_local_server(m_config, networkFactories, jid, cmd);
 
	eventLoop.runUntilEvents();
 
	struct timeval td_start,td_end;
 
	float elapsed = 0; 
 
	gettimeofday(&td_start, NULL);
 

	
 
	time_t started = time(NULL);
 
	while(get_response().empty() && td_end.tv_sec - td_start.tv_sec < 1) {
 
		gettimeofday(&td_end, NULL);
 
		eventLoop.runOnce();
 
	}
 

	
 
	return get_response();
 
}
 

	
 
void Server::serve_onlineusers(struct mg_connection *conn, struct http_message *hm) {
 
	std::string html;
 
	std::string jid = get_http_var(hm, "jid");
 
@@ -244,18 +291,80 @@ void Server::serve_cmd(struct mg_connection *conn, struct http_message *hm) {
 
	print_html(conn, hm, html);
 
}
 

	
 
void Server::serve_users_add(struct mg_connection *conn, struct http_message *hm) {
 
	std::string user = get_http_var(hm, "user");
 
	std::string password = get_http_var(hm, "password");
 

	
 
	if (!user.empty() && !password.empty()) {
 
		UserInfo info;
 
		info.jid = user;
 
		info.password = password;
 
		if (m_storage) {
 
			m_storage->setUser(info);
 
		}
 
	}
 
	redirect_to(conn, hm, "/users");
 
}
 

	
 
void Server::serve_users(struct mg_connection *conn, struct http_message *hm) {
 
	std::string html = "<h2>Spectrum 2 manager users</h2>";
 

	
 
	html += "<p>Here, you can add new users who will have access to this web interface. "
 
			"These users will be able to register new accounts on all Spectrum 2 instances "
 
			"running on these server. They won't be able to change any Spectrum 2 instance "
 
			"configuration influencing other users.</p>";
 

	
 
	if (!m_storage) {
 
		print_html(conn, hm, html);
 
		return;
 
	}
 

	
 
	html += "<form action=\"/users/add\" class=\"basic-grey\" method=\"POST\"> \
 
	<h1>Add user \
 
		<span>Add new user to Spectrum 2 manager web interface.</span> \
 
	</h1> \
 
	<label> \
 
		<span>Username:</span> \
 
		<input type=\"text\" id=\"user\" name=\"user\"placeholder=\"Username\"></textarea> \
 
	</label> \
 
	<label><span>Password:</span> \
 
		<input type=\"password\" id=\"password\" name=\"password\" placeholder=\"Password\"></textarea> \
 
	</label> \
 
	<label> \
 
		<span>&nbsp;</span> \
 
		<input type=\"submit\" class=\"button\" value=\"Add user\" />\
 
	</label> \
 
</form><br/>";
 
	std::vector<std::string> users;
 
	m_storage->getUsers(users);
 

	
 
	html += "<table><tr><th>User<th>Action</th></tr>";
 
	BOOST_FOREACH(std::string &jid, users) {
 
		html += "<tr>";
 
		html += "<td><a href=\"/users?jid=" + jid + "\">" + jid + "</a></td>";
 
		html += "<td> </td>";
 
		html += "</tr>";
 
	}
 
	html += "</table>";
 

	
 
	print_html(conn, hm, html);
 
}
 

	
 
void Server::serve_start(struct mg_connection *conn, struct http_message *hm) {
 
void Server::serve_instances_start(struct mg_connection *conn, struct http_message *hm) {
 
	std::string html;
 
	std::string jid = get_http_var(hm, "jid");
 
	if (jid.empty()) {
 
		redirect_to(conn, hm, "/");
 
		return;
 
	}
 

	
 
	start_instances(m_config, jid);
 
	html += "<h2>Starting Spectrum 2 instance</h2>";
 
	html += "<b>" + get_response() + "</b><br/><a href=\"/\">Back to main page</a>";
 
	html += "</body></html>";
 
	print_html(conn, hm, html);
 
}
 

	
 
void Server::serve_stop(struct mg_connection *conn, struct http_message *hm) {
 
void Server::serve_instances_stop(struct mg_connection *conn, struct http_message *hm) {
 
	std::string html;
 
	std::string jid = get_http_var(hm, "jid");
 

	
 
@@ -264,44 +373,154 @@ void Server::serve_stop(struct mg_connection *conn, struct http_message *hm) {
 
	html += "</body></html>";
 
	print_html(conn, hm, html);
 
}
 
void Server::serve_root(struct mg_connection *conn, struct http_message *hm) {
 
	std::vector<std::string> list = show_list(m_config, false);
 
	std::string html = "<h2>List of instances</h2>";
 

	
 
	if (list.empty()) {
 
		html += "<p>There are no Spectrum 2 instances yet. You can create new instance by adding configuration files into <pre>/etc/spectrum2/transports</pre> directory. You can then maintain the Spectrum 2 instance here.</p>";
 
void Server::serve_instance(struct mg_connection *conn, struct http_message *hm, const std::string &jid) {
 
	std::string html = "<h2>Spectrum 2 instance: " + jid + "</h2>";
 

	
 
	print_html(conn, hm, html);
 
}
 

	
 
void Server::serve_instances_unregister(struct mg_connection *conn, struct http_message *hm) {
 
	
 
}
 

	
 
void Server::serve_instances_register(struct mg_connection *conn, struct http_message *hm) {
 
	std::string instance = get_http_var(hm, "instance");
 
	if (!instance.empty()) {
 
		serve_instance(conn, hm, instance);
 
		return;
 
	}
 

	
 
	std::string jid = get_http_var(hm, "jid");
 
	std::string uin = get_http_var(hm, "uin");
 
	std::string password = get_http_var(hm, "password");
 
	Server:session *session = get_session(hm);
 
	UserInfo info;
 
	m_storage->getUser(session->user, info);
 

	
 
	if (uin.empty() || password.empty()) {
 
		std::string html = "<h2>Register Spectrum 2 instance</h2>";
 
		html += "<form action=\"/instances/register\" class=\"basic-grey\" method=\"POST\"> \
 
			<h1>Register Spectrum 2 instance \
 
				<span>Write the Slack team name, 3rd-party network username and password.</span> \
 
			</h1> \
 
			<label> \
 
				<span>Slack team name:</span> \
 
				<input type=\"text\" id=\"jid\" name=\"jid\"placeholder=\"Slack team name\"></textarea> \
 
			</label> \
 
			<label> \
 
				<span>3rd-party network username:</span> \
 
				<input type=\"text\" id=\"uin\" name=\"uin\"placeholder=\"3rd-party network username\"></textarea> \
 
			</label> \
 
			<label><span>Password:</span> \
 
				<input type=\"password\" id=\"password\" name=\"password\" placeholder=\"3rd-party network password\"></textarea> \
 
			</label> \
 
			<label> \
 
				<span>&nbsp;</span> \
 
				<input type=\"submit\" class=\"button\" value=\"Register\" />\
 
			</label> \
 
			</form><br/>";
 
		print_html(conn, hm, html);
 
	}
 
	else {
 
		html += "<table><tr><th>JID<th>Status</th><th>Command</th><th>Run command</th></tr>";
 
		BOOST_FOREACH(std::string &instance, list) {
 
			html += "<tr>";
 
			html += "<td><a href=\"/onlineusers?jid=" + instance + "\">" + instance + "</a></td>";
 
			Swift::SimpleEventLoop eventLoop;
 
			Swift::BoostNetworkFactories networkFactories(&eventLoop);
 

	
 
			ask_local_server(m_config, networkFactories, instance, "status");
 
			eventLoop.runUntilEvents();
 
			while(get_response().empty()) {
 
				eventLoop.runUntilEvents();
 
			}
 
			html += "<td>" + get_response() + "</td>";
 
			if (get_response().find("Running") == 0) {
 
				html += "<td><a href=\"/stop?jid=" + instance + "\">Stop</a></td>";
 
				html += "<td><form action=\"/cmd\">";
 
				html += "<input type=\"hidden\" name=\"jid\" value=\"" + instance + "\"></input>";
 
				html += "<input type=\"text\" name=\"cmd\"></input>";
 
				html += "<input type=\"submit\" value=\"Run\"></input>";
 
				html += "</form></td>";
 
			}
 
			else {
 
				html += "<td><a href=\"/start?jid=" + instance + "\">Start</a></td>";
 
				html += "<td></td>";
 
		std::string response = send_command(jid, "register " + jid + " " + uin + " " + password);
 
		if (!response.empty()) {
 
			std::string value = jid;
 
			int type = (int) TYPE_STRING;
 
			m_storage->updateUserSetting(info.id, jid, value);
 
		}
 
		redirect_to(conn, hm, "/instances");
 
	}
 

	
 
}
 

	
 
void Server::serve_instances(struct mg_connection *conn, struct http_message *hm) {
 
	std::string jid = get_http_var(hm, "jid");
 
	if (!jid.empty()) {
 
		serve_instance(conn, hm, jid);
 
		return;
 
	}
 

	
 
	std::vector<std::string> list = show_list(m_config, false);
 
	std::string html = "<h2>List of Spectrum 2 instances</h2>";
 

	
 
	Server:session *session = get_session(hm);
 

	
 
	if (session->admin) {
 
		if (list.empty()) {
 
			html += "<p>There are no Spectrum 2 instances yet. You can create new instance by adding configuration files into <pre>/etc/spectrum2/transports</pre> directory. You can then maintain the Spectrum 2 instance here.</p>";
 
		}
 
		else {
 
			html += "<table><tr><th>Hostname<th>Status</th><th>Command</th><th>Run command</th></tr>";
 
			BOOST_FOREACH(std::string &instance, list) {
 
				html += "<tr>";
 
				html += "<td><a href=\"/instances?jid=" + instance + "\">" + instance + "</a></td>";
 

	
 
				std::string response = send_command(instance, "status");
 
				if (response.empty()) {
 
					response = "Cannot get the server status";
 
				}
 

	
 
				html += "<td>" + response + "</td>";
 
				if (response.find("Running") == 0) {
 
					html += "<td><a href=\"/instances/stop?jid=" + instance + "\">Stop</a></td>";
 
					html += "<td><form action=\"/cmd\">";
 
					html += "<input type=\"hidden\" name=\"jid\" value=\"" + instance + "\"></input>";
 
					html += "<input type=\"text\" name=\"cmd\"></input>";
 
					html += "<input type=\"submit\" value=\"Run\"></input>";
 
					html += "</form></td>";
 
				}
 
				else {
 
					html += "<td><a href=\"/instances/start?jid=" + instance + "\">Start</a></td>";
 
					html += "<td></td>";
 
				}
 

	
 
				html += "</tr>";
 
			}
 

	
 
			html += "</tr>";
 
			html += "</table>";
 
		}
 
	}
 
	else {
 
		UserInfo info;
 
		m_storage->getUser(session->user, info);
 

	
 
		html += "</table>";
 
		if (list.empty()) {
 
			html += "<p>There are no Spectrum 2 instances yet.</p>";
 
		}
 
		else {
 
			html += "<table><tr><th>Hostname<th>Status</th><th>Action</th></tr>";
 
			BOOST_FOREACH(std::string &instance, list) {
 
				html += "<tr>";
 
				html += "<td><a href=\"/instances?jid=" + instance + "\">" + instance + "</a></td>";
 

	
 
				std::string response = send_command(instance, "status");
 
				if (response.empty()) {
 
					response = "Cannot get the server status";
 
				}
 

	
 
				html += "<td>" + response + "</td>";
 
				if (response.find("Running") == 0) {
 
					std::string value = "";
 
					int type = (int) TYPE_STRING;
 
					m_storage->getUserSetting(info.id, instance, type, value);
 

	
 
					if (!value.empty()) {
 
						html += "<td><a href=\"/instances/unregister?instance=" + instance + "\">Unregister</a></td>";
 
					}
 
					else {
 
						html += "<td><a href=\"/instances/register?instance=" + instance + "\">Register</a></td>";
 
					}
 
				}
 
				else {
 
					html += "<td>No available action</td>";
 
				}
 

	
 
				html += "</tr>";
 
			}
 

	
 
			html += "</table>";
 
		}
 
	}
 
	print_html(conn, hm, html);
 
}
 
@@ -318,15 +537,25 @@ void Server::event_handler(struct mg_connection *conn, int ev, void *p) {
 
	} else if (mg_vcmp(&hm->uri, "/authorize") == 0) {
 
		authorize(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/") == 0) {
 
		serve_root(conn, hm);
 
		serve_instances(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances") == 0) {
 
		serve_instances(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/onlineusers") == 0) {
 
		serve_onlineusers(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/cmd") == 0) {
 
		serve_cmd(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/start") == 0) {
 
		serve_start(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/stop") == 0) {
 
		serve_stop(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/start") == 0) {
 
		serve_instances_start(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/stop") == 0) {
 
		serve_instances_stop(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/register") == 0) {
 
		serve_instances_register(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/unregister") == 0) {
 
		serve_instances_unregister(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/users") == 0) {
 
		serve_users(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/users/add") == 0) {
 
		serve_users_add(conn, hm);
 
	} else {
 
		mg_serve_http(conn, hm, s_http_server_opts);
 
	}
spectrum_manager/src/server.h
Show inline comments
 
@@ -31,6 +31,14 @@
 
#include "mongoose.h"
 
#include "managerconfig.h"
 

	
 
#include "transport/Config.h"
 
#include "transport/SQLite3Backend.h"
 
#include "transport/MySQLBackend.h"
 
#include "transport/PQXXBackend.h"
 
#include "transport/StorageBackend.h"
 

	
 
using namespace Transport;
 

	
 
class Server {
 
	public:
 
		struct session {
 
@@ -42,7 +50,7 @@ class Server {
 
		};
 

	
 
		/// Constructor.
 
		Server(ManagerConfig *config);
 
		Server(ManagerConfig *config, const std::string &config_file);
 

	
 
		/// Destructor
 
		virtual ~Server();
 
@@ -52,12 +60,18 @@ class Server {
 
		void event_handler(struct mg_connection *nc, int ev, void *p);
 

	
 
	private:
 
		void serve_root(struct mg_connection *conn, struct http_message *hm);
 
		void serve_start(struct mg_connection *conn, struct http_message *hm);
 
		void serve_stop(struct mg_connection *conn, struct http_message *hm);
 
		void serve_instance(struct mg_connection *conn, struct http_message *hm, const std::string &jid);
 
		void serve_instances(struct mg_connection *conn, struct http_message *hm);
 
		void serve_instances_start(struct mg_connection *conn, struct http_message *hm);
 
		void serve_instances_stop(struct mg_connection *conn, struct http_message *hm);
 
		void serve_instances_register(struct mg_connection *conn, struct http_message *hm);
 
		void serve_instances_unregister(struct mg_connection *conn, struct http_message *hm);
 
		void serve_users(struct mg_connection *conn, struct http_message *hm);
 
		void serve_users_add(struct mg_connection *conn, struct http_message *hm);
 
		void serve_onlineusers(struct mg_connection *conn, struct http_message *hm);
 
		void serve_cmd(struct mg_connection *conn, struct http_message *hm);
 
		void print_html(struct mg_connection *conn, struct http_message *hm, const std::string &html);
 
		std::string send_command(const std::string &jid, const std::string &cmd);
 

	
 
	private:
 
		bool check_password(const std::string &user, const std::string &password);
 
@@ -80,4 +94,6 @@ class Server {
 
		ManagerConfig *m_config;
 
		std::string m_header;
 
		std::string m_footer;
 
		Config *m_storageCfg;
 
		StorageBackend *m_storage;
 
};
spectrum_manager/src/spectrum_manager.cfg
Show inline comments
 
@@ -3,6 +3,10 @@ admin_username=admin
 
admin_password=test
 
config_directory=/etc/spectrum2/transports/
 

	
 
[database]
 
type=sqlite3
 
database=/var/lib/spectrum2_manager/database.sql
 

	
 
[servers]
 
server=localhost
 
#server=icq.spectrum.im
tests/twitter/twitter_test.py
Show inline comments
 
@@ -36,6 +36,7 @@ class Client(sleekxmpp.ClientXMPP):
 
		self.tests["friends"] = ["#friends command", False]
 
		self.tests["unfollow"] = ["#unfollow command", False]
 
		self.tests["friends2"] = ["#friends after unfollow command", False]
 
		self.tests["mode1"] = ["#mode 1", False]
 

	
 
		self.status = "timeline"
 
		self.timestamp = int(time.time())
 
@@ -60,16 +61,16 @@ class Client(sleekxmpp.ClientXMPP):
 
			self.tests["follow"][1] = True
 
			self.send_message(mto=msg['from'], mbody="#friends")
 
		elif self.status == "friends" and msg['body'].find("USER LIST") != -1 and msg['body'].find("colinpwheeler") != -1:
 
			self.status = "unfollow"
 
			self.tests["friends"][1] = True
 
			self.send_message(mto=msg['from'], mbody="#unfollow colinpwheeler")
 
		elif self.status == "unfollow" and msg['body'] == "You are not following colinpwheeler anymore":
 
			self.status = "friends2"
 
			self.tests["unfollow"][1] = True
 
			self.send_message(mto=msg['from'], mbody="#friends")
 
		elif self.status == "friends2" and msg['body'].find("USER LIST") != -1 and msg['body'].find("colinpwheeler") == -1:
 
			self.tests["friends2"][1] = True
 
			self.finished = True
 
			#self.status = "unfollow"
 
			#self.tests["friends"][1] = True
 
			#self.send_message(mto=msg['from'], mbody="#unfollow colinpwheeler")
 
		#elif self.status == "unfollow" and msg['body'] == "You are not following colinpwheeler anymore":
 
			#self.status = "friends2"
 
			#self.tests["unfollow"][1] = True
 
			#self.send_message(mto=msg['from'], mbody="#friends")
 
		#elif self.status == "friends2" and msg['body'].find("USER LIST") != -1 and msg['body'].find("colinpwheeler") == -1:
 
			#self.tests["friends2"][1] = True
 
			self.send_message(mto=msg['from'], mbody="#mode 1")
 

	
 
	def start(self, event):
 
		self.getRoster()
0 comments (0 inline, 0 general)