(purple) Loading Cardie-side account settings into PurpleAccount

This commit is contained in:
Jaidyn Ann 2021-06-26 20:40:39 -05:00
parent 543986f281
commit 0aea480ec2
5 changed files with 169 additions and 23 deletions

View File

@ -50,18 +50,18 @@ void
PurpleApp::MessageReceived(BMessage* msg)
{
int64 thread_id;
if (msg->FindInt64("thread_id", &thread_id) != B_OK)
return;
switch (msg->what)
{
case PURPLE_REQUEST_PROTOCOL_COUNT:
{
if (msg->FindInt64("thread_id", &thread_id) != B_OK) return;
send_data(thread_id, fProtocols.CountItems(), NULL, 0);
break;
}
case PURPLE_REQUEST_PROTOCOL_INFO:
{
if (msg->FindInt64("thread_id", &thread_id) != B_OK) return;
int32 index = msg->FindInt32("index", 0);
ProtocolInfo* info = fProtocols.ItemAt(index);
@ -78,6 +78,11 @@ PurpleApp::MessageReceived(BMessage* msg)
send_data(thread_id, 0, buffer, size);
break;
}
case PURPLE_LOAD_ACCOUNT:
{
_ParseCardieSettings(msg);
break;
}
default:
BApplication::MessageReceived(msg);
}
@ -115,7 +120,45 @@ PurpleApp::_ParseProtoOptions(PurplePluginProtocolInfo* info)
{
BMessage temp;
// Add a "username" setting, if not explicitly specified
GList* prefIter = info->protocol_options;
for (int i = 0; prefIter != NULL; prefIter = prefIter->next) {
PurpleAccountOption* pref = (PurpleAccountOption*)prefIter->data;
if (pref->pref_name == BString("username"))
break;
else if (prefIter->next == NULL) {
BMessage setting;
setting.AddString("name", "username");
setting.AddString("description", "Username");
setting.AddString("error", "A username needs to be specified!");
setting.AddInt32("type", B_STRING_TYPE);
temp.AddMessage("setting", &setting);
}
}
// Add any UserSplits (that is, parts of the protocols 'username' format)
GList* splitIter = info->user_splits;
for (int i = 0; splitIter != NULL; splitIter = splitIter->next)
{
PurpleAccountUserSplit* split = (PurpleAccountUserSplit*)splitIter->data;
BMessage setting;
setting.AddString("name", "username_split");
setting.AddString("description", split->text);
setting.AddString("default", split->default_value);
setting.AddInt32("type", B_STRING_TYPE);
temp.AddMessage("setting", &setting);
}
// Password setting
BMessage passwd;
passwd.AddString("name", "password");
passwd.AddString("description", "Password");
passwd.AddInt32("type", B_STRING_TYPE);
temp.AddMessage("setting", &passwd);
// Whatever custom settings the protocol might like!
prefIter = info->protocol_options;
for (int i = 0; prefIter != NULL; prefIter = prefIter->next)
{
PurpleAccountOption* pref = (PurpleAccountOption*)prefIter->data;
@ -140,15 +183,6 @@ PurpleApp::_ParseProtoOptions(PurplePluginProtocolInfo* info)
setting.AddInt32("default", pref->default_value.integer);
break;
}
case PURPLE_PREF_STRING_LIST: {
bType = B_STRING_TYPE;
BString implicit;
GList* lists;
for (int j = 0; lists != NULL; lists = lists->next)
implicit << " " << lists->data;
setting.AddString("default", implicit);
break;
}
default:
bType = B_STRING_TYPE;
setting.AddString("default", pref->default_value.string);
@ -160,11 +194,92 @@ PurpleApp::_ParseProtoOptions(PurplePluginProtocolInfo* info)
setting.AddInt32("type", bType);
temp.AddMessage("setting", &setting);
}
return temp;
}
void
PurpleApp::_ParseCardieSettings(BMessage* settings)
{
PurplePlugin* plugin = _PluginFromMessage(settings);
PurplePluginProtocolInfo* info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
const char* protoId = settings->FindString("signature");
if (plugin == NULL || info == NULL)
return;
// Fetch and cobble together the username & password
BString username, password;
settings->FindString("username", &username);
settings->FindString("password", &password);
GList* splitIter = info->user_splits;
for (int i = 0; splitIter != NULL; splitIter = splitIter->next)
{
PurpleAccountUserSplit* split = (PurpleAccountUserSplit*)splitIter->data;
username << split->field_sep;
BString opt;
if (settings->FindString("username_split", i, &opt) == B_OK)
username << opt;
else
username << split->default_value;
i++;
}
std::cout << username << " of \n";
// Create/fetch the account itself
PurpleAccount* account = purple_accounts_find(username.String(), protoId);
if (account == NULL) {
account = purple_account_new(username.String(), protoId);
purple_account_set_password(account, password.String());
purple_accounts_add(account);
}
// Set all protocol settings
GList* prefIter = info->protocol_options;
for (int i = 0; prefIter != NULL; prefIter = prefIter->next)
{
PurpleAccountOption* pref = (PurpleAccountOption*)prefIter->data;
PurplePrefType type = pref->type;
switch (type)
{
case PURPLE_PREF_BOOLEAN:
{
bool value;
if (settings->FindBool(pref->pref_name, &value) == B_OK)
purple_account_set_bool(account, pref->pref_name, value);
break;
}
case PURPLE_PREF_INT:
{
int32 value;
if (settings->FindInt32(pref->pref_name, &value) == B_OK)
purple_account_set_int(account, pref->pref_name, value);
break;
}
default:
{
BString value;
if (settings->FindString(pref->pref_name, &value) == B_OK)
purple_account_set_string(account, pref->pref_name,
value.String());
}
}
}
fAccounts.AddItem(settings->FindString("account_name"), username);
}
PurplePlugin*
PurpleApp::_PluginFromMessage(BMessage* msg)
{
return purple_plugins_find_with_id(msg->FindString("signature"));
}
static PurpleEventLoopUiOps _glib_eventloops =
{
g_timeout_add,

View File

@ -27,9 +27,14 @@
#include <ObjectList.h>
#include <StringList.h>
#include <libsupport/KeyMap.h>
#include "PurpleMessages.h"
typedef KeyMap<BString, BString> Accounts;
#define PURPLE_GLIB_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR)
#define PURPLE_GLIB_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
@ -58,8 +63,13 @@ public:
private:
void _GetProtocolsInfo();
void _SaveProtocolInfo(PurplePlugin* plugin);
BMessage _ParseProtoOptions(PurplePluginProtocolInfo* info);
BMessage _ParseProtoOptions(PurplePluginProtocolInfo* info);
void _ParseCardieSettings(BMessage* settings);
PurplePlugin* _PluginFromMessage(BMessage* msg);
Accounts fAccounts;
BObjectList<ProtocolInfo> fProtocols;
};

View File

@ -30,7 +30,7 @@ enum purple_message {
* Response is sent directly to the requesting thread
* as a message's code, use receive_data() to catch it.
* Requires: int64 thread_id */
PURPLE_REQUEST_PROTOCOL_COUNT = 1,
PURPLE_REQUEST_PROTOCOL_COUNT = 'PApc',
/*! Request protocol metadata. →Server
* Response is sent directly to the requesting thread
@ -38,8 +38,14 @@ enum purple_message {
* the first sending the size of the subsequently sent
* flattened BMessage.
* Requires: int32 protocol_index, int64 thread_id */
PURPLE_REQUEST_PROTOCOL_INFO = 2
PURPLE_REQUEST_PROTOCOL_INFO = 'PApi',
/*! Load/start connecting the account →Server
* Just the account's settings message from Cardie's end.
* It's the server's job to tie the Cardie account name
* to the PurpleAccount. */
PURPLE_LOAD_ACCOUNT = 'PAla'
};
#endif // _PURPLE_MESSAGESH
#endif // _PURPLE_MESSAGES_H

View File

@ -63,8 +63,7 @@ protocol_count()
ensure_app_messenger()->SendMessage(msg);
thread_id sender;
int32 count = receive_data(&sender, NULL, 0);
return count;
return receive_data(&sender, NULL, 0);
}
@ -159,13 +158,17 @@ PurpleProtocol::Process(BMessage* msg)
status_t
PurpleProtocol::UpdateSettings(BMessage* msg)
{
thread_id thread = spawn_thread(connect_thread, "connect_thread",
B_NORMAL_PRIORITY, (void*)this);
ensure_app();
fPrplMessenger = new BMessenger("application/x-vnd.cardie.purple");
msg->what = PURPLE_LOAD_ACCOUNT;
_SendPrplMessage(msg);
// thread_id thread = spawn_thread(connect_thread, "connect_thread",
// B_NORMAL_PRIORITY, (void*)this);
if (thread < B_OK)
return B_ERROR;
// if (thread < B_OK)
// return B_ERROR;
resume_thread(thread);
// resume_thread(thread);
return B_OK;
}
@ -265,3 +268,13 @@ PurpleProtocol::MessengerInterface() const
{
return fMessenger;
}
void
PurpleProtocol::_SendPrplMessage(BMessage* msg)
{
msg->AddString("account_name", fName);
msg->AddString("signature", fSignature);
if (fPrplMessenger->IsValid())
fPrplMessenger->SendMessage(msg);
}

View File

@ -75,7 +75,9 @@ public:
MessengerInterface() const;
private:
void _SendPrplMessage(BMessage* msg);
ChatProtocolMessengerInterface* fMessenger;
BMessenger* fPrplMessenger;
thread_id fServerThread;
BString fName;