Changeset - d7527b44b290
[Not reviewed]
0 1 0
Florian Kinder - 7 years ago 2018-12-01 10:25:47
florian.kinder@fankserver.com
Added multi tree support in roomlist
1 file changed with 61 insertions and 21 deletions:
0 comments (0 inline, 0 general)
backends/libpurple/main.cpp
Show inline comments
 
@@ -749,102 +749,105 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
 
			if (account) {
 
				serv_send_typing_wrapped(purple_account_get_connection_wrapped(account), buddyName.c_str(), PURPLE_NOT_TYPING);
 
				updateConversationActivity(account, buddyName);
 
			}
 
		}
 

	
 
		void handleAttentionRequest(const std::string &user, const std::string &buddyName, const std::string &message) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (account) {
 
				purple_prpl_send_attention_wrapped(purple_account_get_connection_wrapped(account), buddyName.c_str(), 0);
 
			}
 
		}
 

	
 
		std::string LegacyNameToName(PurpleAccount *account, const std::string &legacyName) {
 
			std::string conversationName = legacyName;
 
			BOOST_FOREACH(std::string _room, m_rooms[np->m_accounts[account]]) {
 
				std::string lowercased_room = boost::locale::to_lower(_room);
 
				if (lowercased_room.compare(conversationName) == 0) {
 
					conversationName = _room;
 
					break;
 
				}
 
			}
 
			return conversationName;
 
		}
 

	
 
		std::string NameToLegacyName(PurpleAccount *account, const std::string &legacyName) {
 
			std::string conversationName = legacyName;
 
			BOOST_FOREACH(std::string _room, m_rooms[np->m_accounts[account]]) {
 
				if (_room.compare(conversationName) == 0) {
 
					conversationName = boost::locale::to_lower(legacyName);
 
					break;
 
				}
 
			}
 
			return conversationName;
 
		}
 

	
 
		void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &pasword) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (!account) {
 
				return;
 
			}
 

	
 
			PurpleConnection *gc = purple_account_get_connection_wrapped(account);
 
			GHashTable *comps = NULL;
 
			std::string roomName = LegacyNameToName(account, room);
 
			// Check if the PurpleChat is not stored in buddy list
 
			PurpleChat *chat = purple_blist_find_chat_wrapped(account, roomName.c_str());
 
			if (chat) {
 
				LOG4CXX_INFO(logger, "CHAT FOUND");
 
				comps = purple_chat_get_components_wrapped(chat);
 
			}
 
			else if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) {
 
				LOG4CXX_INFO(logger, "CHAT NOT FOUND");
 
				if (CONFIG_STRING(config, "service.protocol") == "prpl-jabber") {
 
					comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, (roomName + "/" + nickname).c_str());
 
				} else {
 
				}
 
				else {
 
					comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, roomName.c_str());
 
				}
 
			}
 

	
 
			if (CONFIG_STRING(config, "service.protocol") != "prpl-jabber") {
 
                               np->handleParticipantChanged(np->m_accounts[account], nickname, room, 0, pbnetwork::STATUS_ONLINE);
 
                               const char *disp;
 
                               if ((disp = purple_account_get_name_for_display(account)) == NULL) {
 
                                       if ((disp = purple_connection_get_display_name(account->gc)) == NULL) {
 
                                               disp = purple_account_get_username(account);
 
                                       }
 
                               }
 
                               LOG4CXX_INFO(logger, user << ": Display name is " << disp << ", nickname is " << nickname);
 
                               if (nickname != disp) {
 
                                       handleRoomNicknameChanged(np->m_accounts[account], room, disp);
 
                                       np->handleParticipantChanged(np->m_accounts[account], nickname, room, 0, pbnetwork::STATUS_ONLINE, "", disp);
 
                               }
 
			}
 

	
 
			LOG4CXX_INFO(logger, user << ": Joining the room " << roomName);
 
			if (comps) {
 
				serv_join_chat_wrapped(gc, comps);
 
				g_hash_table_destroy(comps);
 
			}
 
		}
 

	
 
		void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
 
			PurpleAccount *account = m_sessions[user];
 
			if (!account) {
 
				return;
 
			}
 

	
 
			PurpleConversation *conv = purple_find_conversation_with_account_wrapped(PURPLE_CONV_TYPE_CHAT, LegacyNameToName(account, room).c_str(), account);
 
			purple_conversation_destroy_wrapped(conv);
 
		}
 

	
 
		void handleFTStartRequest(const std::string &user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID) {
 
			PurpleXfer *xfer = m_unhandledXfers[user + fileName + buddyName];
 
			if (xfer) {
 
				m_unhandledXfers.erase(user + fileName + buddyName);
 
				FTData *ftData = (FTData *) xfer->ui_data;
 

	
 
				ftData->id = ftID;
 
				m_xfers[ftID] = xfer;
 
				purple_xfer_request_accepted_wrapped(xfer, fileName.c_str());
 
				purple_xfer_ui_ready_wrapped(xfer);
 
			}
 
		}
 
@@ -1409,96 +1412,97 @@ static void conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gbool
 
// 			item->addAttribute("role", "moderator");
 
			flags = 1;
 
		}
 
		else if (flags & PURPLE_CBFLAGS_FOUNDER) {
 
// 			item->addAttribute("affiliation", "owner");
 
// 			item->addAttribute("role", "moderator");
 
			flags = 1;
 
		}
 
		else {
 
			flags = 0;
 
// 			item->addAttribute("affiliation", "member");
 
// 			item->addAttribute("role", "participant");
 
		}
 
		std::string conversationName = purple_conversation_get_name_wrapped(conv);
 
		np->handleParticipantChanged(np->m_accounts[account], name, np->NameToLegacyName(account, conversationName), (int) flags, pbnetwork::STATUS_ONLINE, "", "", alias);
 

	
 
		l = l->next;
 
	}
 
}
 

	
 
static void conv_chat_remove_users(PurpleConversation *conv, GList *users) {
 
	PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
 

	
 
	GList *l = users;
 
	while (l != NULL) {
 
		std::string name((char *) l->data);
 
		std::string conversationName = purple_conversation_get_name_wrapped(conv);
 
		np->handleParticipantChanged(np->m_accounts[account], name, np->NameToLegacyName(account, conversationName), 0, pbnetwork::STATUS_NONE);
 

	
 
		l = l->next;
 
	}
 
}
 

	
 
static gboolean conv_has_focus(PurpleConversation *conv) {
 
	return TRUE;
 
}
 

	
 
static void conv_chat_topic_changed(PurpleConversation *conv, const char *who, const char *topic) {
 
	LOG4CXX_INFO(logger, "Conversation topic changed");
 
	PurpleAccount *account = purple_conversation_get_account_wrapped(conv);
 
	np->handleSubject(np->m_accounts[account], np->NameToLegacyName(account, purple_conversation_get_name_wrapped(conv)), topic ? topic : "", who ? who : "Spectrum 2");
 
}
 

	
 
static void conv_present(PurpleConversation *conv) {
 
	if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_CHAT) {
 
		LOG4CXX_INFO(logger, "Conversation presented");
 
		conv_chat_add_users(conv, PURPLE_CONV_CHAT_WRAPPED(conv)->in_room, TRUE);
 
		const char *topic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT_WRAPPED(conv));
 
		LOG4CXX_INFO(logger, "topic: " << topic);
 
		if (topic && *topic != '\0') {
 
			conv_chat_topic_changed(conv, topic, PURPLE_CONV_CHAT_WRAPPED(conv)->who);
 
		}
 
		else {
 
			LOG4CXX_INFO(logger, "Conversation created with an empty topic");
 
		}
 
	}
 
}
 

	
 
static PurpleConversationUiOps conversation_ui_ops =
 
{
 
	NULL,
 
	NULL,
 
	conv_write_im,//conv_write_chat,                              /* write_chat           */
 
	conv_write_im,             /* write_im             */
 
	conv_write,//conv_write_conv,           /* write_conv           */
 
	conv_chat_add_users,       /* chat_add_users       */
 
	NULL,//conv_chat_rename_user,     /* chat_rename_user     */
 
	conv_chat_remove_users,    /* chat_remove_users    */
 
	NULL,//pidgin_conv_chat_update_user,     /* chat_update_user     */
 
	conv_present,//pidgin_conv_present_conversation, /* present              */
 
	conv_has_focus,//pidgin_conv_has_focus,            /* has_focus            */
 
	NULL,//pidgin_conv_custom_smiley_add,    /* custom_smiley_add    */
 
	NULL,//pidgin_conv_custom_smiley_write,  /* custom_smiley_write  */
 
	NULL,//pidgin_conv_custom_smiley_close,  /* custom_smiley_close  */
 
	NULL,//pidgin_conv_send_confirm,         /* send_confirm         */
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL
 
};
 

	
 
struct Dis {
 
	std::string name;
 
	std::string protocol;
 
};
 

	
 
// currently unused
 
#if 0
 
static gboolean disconnectMe(void *data) {
 
	Dis *d = (Dis *) data;
 
	PurpleAccount *account = purple_accounts_find_wrapped(d->name.c_str(), d->protocol.c_str());
 
	delete d;
 

	
 
	if (account) {
 
		np->handleLogoutRequest(np->m_accounts[account], purple_account_get_username_wrapped(account));
 
	}
 
	return FALSE;
 
@@ -1880,151 +1884,187 @@ static void XferSendComplete(PurpleXfer *xfer) {
 
static gssize XferWrite(PurpleXfer *xfer, const guchar *buffer, gssize size) {
 
	FTData *ftData = (FTData *) xfer->ui_data;
 
	std::string data((const char *) buffer, (size_t) size);
 
// 	std::cout << "xferwrite\n";
 
	if (!ftData->paused) {
 
// 		std::cout << "adding xfer to waitingXfers queue\n";
 
		np->m_waitingXfers.push_back(xfer);
 
	}
 
	np->handleFTData(ftData->id, data);
 
	return size;
 
}
 

	
 
static void XferNotSent(PurpleXfer *xfer, const guchar *buffer, gsize size) {
 
// 	FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
 
// 	repeater->handleDataNotSent(buffer, size);
 
}
 

	
 
static gssize XferRead(PurpleXfer *xfer, guchar **buffer, gssize size) {
 
// 	FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
 
// 	int data_size = repeater->getDataToSend(buffer, size);
 
// 	if (data_size == 0)
 
// 		return 0;
 
//
 
// 	return data_size;
 
	return 0;
 
}
 

	
 
static PurpleXferUiOps xferUiOps =
 
{
 
	XferCreated,
 
	XferDestroyed,
 
	NULL,
 
	NULL,
 
	xferCanceled,
 
	xferCanceled,
 
	XferWrite,
 
	XferRead,
 
	XferNotSent,
 
	NULL
 
};
 

	
 
static void RoomlistProgress(PurpleRoomlist *list, gboolean in_progress)
 
{
 
	if (!in_progress) {
 
		GList *fields = purple_roomlist_get_fields(list);
 
		GList *field;
 
		int topicId = -1;
 
		int usersId = -1;
 
		int descriptionId = -1;
 
		int roomId = -1;
 
		int id = 0;
 
		for (field = fields; field != NULL; field = field->next, id++) {
 
			PurpleRoomlistField *f = (PurpleRoomlistField *) field->data;
 
			if (!f || !f->name) {
 
				continue;
 
			}
 
			std::string fstring = f->name;
 
			if (fstring == "topic") {
 
			if (fstring == "id") {
 
				roomId = id;
 
			}
 
			else if (fstring == "topic" || fstring == "name") {
 
				topicId = id;
 
			}
 
			else if (fstring == "users") {
 
				usersId = id;
 
			}
 
			else if (fstring == "type") {
 
				descriptionId = id;
 
			}
 
			else {
 
				LOG4CXX_INFO(logger, "Uknown RoomList field " << fstring);
 
			}
 
		}
 

	
 
		GList *rooms;
 
		std::list<std::string> m_topics;
 
		PurplePlugin *plugin = purple_find_prpl_wrapped(purple_account_get_protocol_id_wrapped(list->account));
 
		PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
 
		for (rooms = list->rooms; rooms != NULL; rooms = rooms->next) {
 
			PurpleRoomlistRoom *room = (PurpleRoomlistRoom *)rooms->data;
 
			if (room->type == PURPLE_ROOMLIST_ROOMTYPE_CATEGORY) continue;
 
			std::string roomId = prpl_info && prpl_info->roomlist_room_serialize ?
 
				prpl_info->roomlist_room_serialize(room)
 
				: room->name;
 
			np->m_rooms[np->m_accounts[list->account]].push_back(roomId);
 

	
 
			std::string roomIdentifier = room->name;
 
			if (roomId != -1) {
 
				char *roomIdField = (char *) g_list_nth_data(purple_roomlist_room_get_fields(room), roomId);
 
				if (roomIdField) {
 
					roomIdentifier = std::string(roomIdField);
 
				}
 
			}
 
			np->m_rooms[np->m_accounts[list->account]].push_back(roomIdentifier);
 
			
 
			std::string roomName = "";
 
			int nestedLevel = 0;
 
			PurpleRoomlistRoom *parentRoom = purple_roomlist_room_get_parent(room);
 
			while (parentRoom != NULL) {
 
				nestedLevel++;
 
				parentRoom = purple_roomlist_room_get_parent(parentRoom);
 
			}
 
			LOG4CXX_INFO(logger, "nestedLevel " << nestedLevel);
 

	
 
			if (nestedLevel > 0) {
 
				std::string roomNamePrefix = std::string(nestedLevel, '-');
 
				if (roomNamePrefix != "") {
 
					roomNamePrefix = roomNamePrefix + "> ";
 
				}
 
				roomName = roomNamePrefix;
 
			}
 

	
 
			if (topicId == -1) {
 
				m_topics.push_back(room->name);
 
				roomName += room->name;
 
			}
 
			else {
 
				char *topic = (char *) g_list_nth_data(purple_roomlist_room_get_fields(room), topicId);
 
				if (topic) {
 
					m_topics.push_back(topic);
 
					roomName += topic;
 
				}
 
				else {
 
					if (usersId) {
 
						char *users = (char *) g_list_nth_data(purple_roomlist_room_get_fields(room), usersId);
 
						if (users) {
 
							m_topics.push_back(users);
 
						}
 
						else {
 
							LOG4CXX_WARN(logger, "RoomList topic and users is NULL");
 
							m_topics.push_back(room->name);
 
						}
 
				else if (usersId) {
 
					char *users = (char *) g_list_nth_data(purple_roomlist_room_get_fields(room), usersId);
 
					if (users) {
 
						roomName += users;
 
					}
 
					else {
 
						LOG4CXX_WARN(logger, "RoomList topic is NULL");
 
						m_topics.push_back(room->name);
 
						LOG4CXX_WARN(logger, "RoomList topic and users is NULL");
 
						roomName += room->name;
 
					}
 
				}
 
				else {
 
					LOG4CXX_WARN(logger, "RoomList topic is NULL");
 
					roomName += room->name;
 
				}
 
			}
 

	
 
			if (descriptionId != -1) {
 
				char *description = (char *) g_list_nth_data(purple_roomlist_room_get_fields(room), descriptionId);
 
				if (description) {
 
					roomName += " (" + std::string(description) + ")";
 
				}
 
			}
 
			
 
			m_topics.push_back(roomName);
 
		}
 

	
 
		std::string user = "";
 
		if (list->account) {
 
			user = np->m_accounts[list->account];
 
		}
 

	
 
		LOG4CXX_INFO(logger, "RoomList is fetched for user " << user);
 
		np->handleRoomList(user, np->m_rooms[user], m_topics);
 
	}
 
	else {
 
		LOG4CXX_INFO(logger, "RoomList is still in progress");
 
	}
 
}
 

	
 
static PurpleRoomlistUiOps roomlist_ui_ops =
 
{
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL,
 
	RoomlistProgress,
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL,
 
	NULL
 
};
 

	
 
static void transport_core_ui_init(void)
 
{
 
	purple_blist_set_ui_ops_wrapped(&blistUiOps);
 
	purple_accounts_set_ui_ops_wrapped(&accountUiOps);
 
	purple_notify_set_ui_ops_wrapped(&notifyUiOps);
 
	purple_request_set_ui_ops_wrapped(&requestUiOps);
 
	purple_xfers_set_ui_ops_wrapped(&xferUiOps);
 
	purple_connections_set_ui_ops_wrapped(&conn_ui_ops);
 
	purple_conversations_set_ui_ops_wrapped(&conversation_ui_ops);
 
	purple_roomlist_set_ui_ops_wrapped(&roomlist_ui_ops);
 

	
 
// #ifndef WIN32
 
// 	purple_dnsquery_set_ui_ops_wrapped(getDNSUiOps());
 
// #endif
 
}
 

	
 
/***** Core Ui Ops *****/
 
static void
 
spectrum_glib_log_handler(const gchar *domain,
0 comments (0 inline, 0 general)