summaryrefslogtreecommitdiffstats
blob: aec821aa3967d1431aad782443aa0ccd1e0ff111 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Copyright (c) 2011 Kevin Smith
 * Licensed under the GNU General Public License v3.
 * See Documentation/Licenses/GPLv3.txt for more information.
 */

#include <Swiftob/MUCs.h>

#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include <Swiften/Base/foreach.h>
#include <Swiften/Client/Client.h>
#include <Swiften/MUC/MUC.h>
#include <Swiften/MUC/MUCManager.h>
#include <Swiften/Base/String.h>

#include <Swiftob/Storage.h>

using namespace Swift;

#define MUC_LIST_SETTING "muc_list"
#define NICK "default_nick"

typedef std::pair<JID, MUC::ref> JIDMUCPair;

MUCs::MUCs(Client* client, Storage* storage) : defaultNick_("Kanchil+") {
	client_ = client;
	storage_ = storage;
	std::string storedNick = storage_->getSetting(NICK);
	if (!storedNick.empty()) {
		defaultNick_ = storedNick;
	}
	client_->onConnected.connect(boost::bind(&MUCs::handleConnected, this));
}

void MUCs::handleConnected() {
	foreach (std::string room, String::split(storage_->getSetting(MUC_LIST_SETTING), ' ')) {
		join(JID(room), boost::bind(&MUCs::handleInitialJoinSuccess, this), boost::bind(&MUCs::handleInitialJoinFailure, this, _1));
	}
}

void MUCs::handleInitialJoinSuccess() {

}

void MUCs::handleInitialJoinFailure(const std::string&) {

}

void MUCs::join(const JID& room, boost::signal<void (const std::string&)>::slot_type successCallback, boost::function<void(const std::string& /*reason*/)> failureCallback) {
	if (contains(room)) {
		failureCallback("Already in room");
	}
	mucs_[room] = client_->getMUCManager()->createMUC(room);
	mucs_[room]->onJoinComplete.connect(successCallback);
	mucs_[room]->onJoinFailed.connect(boost::bind(&MUCs::handleJoinFailed, this, room, _1, failureCallback));
	mucs_[room]->joinWithContextSince(defaultNick_, boost::posix_time::microsec_clock::universal_time());
	save();
}

void MUCs::part(const JID& room) {
	if (!contains(room)) {
		return;
	}
	mucs_[room]->part();
}

bool MUCs::contains(const JID& room) {
	return mucs_.find(room) != mucs_.end();
}

void MUCs::handleJoinFailed(const JID& muc, ErrorPayload::ref error, boost::function<void(const std::string& /*reason*/)> failureCallback) {
	std::string errorMessage("Couldn't join room");
	if (error) {
		switch (error->getCondition()) {
			case ErrorPayload::Conflict:
			//	rejoinNick = nick_ + "_";
				errorMessage += ": Nickname in use";
			//				errorMessage = str(format("Unable to enter this room as %1%, retrying as %2%") % nick_ % rejoinNick);
				break;
			case ErrorPayload::JIDMalformed:
				errorMessage += ": ";
				errorMessage += "No nickname specified";
				break;
			case ErrorPayload::NotAuthorized:
				errorMessage += ": ";
				errorMessage += "A password needed";
				break;
			case ErrorPayload::RegistrationRequired:
				errorMessage += ": ";
				errorMessage += "Only members may enter";
				break;
			case ErrorPayload::Forbidden:
				errorMessage += ": ";
				errorMessage += "You are banned from the room";
				break;
			case ErrorPayload::ServiceUnavailable:
				errorMessage += ": ";
				errorMessage += "The room is full";
				break;
			case ErrorPayload::ItemNotFound:
				errorMessage += ": ";
				errorMessage += "The room does not exist";
				break;
			default:
				break;
		}
		if (!error->getText().empty()) {
			errorMessage += " - " + error->getText();
		}
	}
	mucs_.erase(muc);
	failureCallback(errorMessage);
}

void MUCs::save() {
	std::string concat;
	foreach (JIDMUCPair pair, mucs_) {
		concat += pair.first.toString() + " ";
	}
	storage_->saveSetting(MUC_LIST_SETTING, concat);
}

MUC::ref MUCs::getMUC(const JID& room) {
	return (mucs_.find(room) != mucs_.end()) ? mucs_[room] : MUC::ref();
}

bool MUCs::setDefaultNick(const std::string& nick) {
	JID testJID("alice", "wonderland.lit", nick);
	if (testJID.isValid()) {
		defaultNick_ = testJID.getResource();
		storage_->saveSetting(NICK, defaultNick_);
		return true;
	}
	return false;
}