/*
* SkypeWeb Plugin for libpurple/Pidgin
* Copyright (c) 2014-2020 Eion Robb
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "libskypeweb.h"
#include "skypeweb_connection.h"
#include "skypeweb_contacts.h"
#include "skypeweb_login.h"
#include "skypeweb_messages.h"
#include "skypeweb_util.h"
void
skypeweb_do_all_the_things(SkypeWebAccount *sa)
{
skypeweb_get_vdms_token(sa);
if (!sa->username) {
skypeweb_get_self_details(sa);
} else
if (sa->registration_token) {
skypeweb_get_self_details(sa);
if (sa->authcheck_timeout)
g_source_remove(sa->authcheck_timeout);
skypeweb_check_authrequests(sa);
sa->authcheck_timeout = g_timeout_add_seconds(120, (GSourceFunc)skypeweb_check_authrequests, sa);
purple_connection_set_state(sa->pc, PURPLE_CONNECTION_CONNECTED);
skypeweb_get_friend_list(sa);
skypeweb_poll(sa);
skype_web_get_offline_history(sa);
skypeweb_set_status(sa->account, purple_account_get_active_status(sa->account));
} else {
//Too soon!
skypeweb_get_registration_token(sa);
}
}
/******************************************************************************/
/* PRPL functions */
/******************************************************************************/
static const char *
skypeweb_list_icon(PurpleAccount *account, PurpleBuddy *buddy)
{
if (buddy != NULL) {
const gchar *buddy_name = purple_buddy_get_name(buddy);
if (buddy_name && SKYPEWEB_BUDDY_IS_MSN(buddy_name)) {
return "msn";
}
}
return "skype";
}
static gchar *
skypeweb_status_text(PurpleBuddy *buddy)
{
SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy);
if (sbuddy && sbuddy->mood && *(sbuddy->mood))
{
gchar *stripped = purple_markup_strip_html(sbuddy->mood);
gchar *escaped = g_markup_printf_escaped("%s", stripped);
g_free(stripped);
return escaped;
}
return NULL;
}
void
skypeweb_tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full)
{
SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy);
if (sbuddy)
{
PurplePresence *presence;
PurpleStatus *status;
SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy);
presence = purple_buddy_get_presence(buddy);
status = purple_presence_get_active_status(presence);
purple_notify_user_info_add_pair_html(user_info, _("Status"), purple_status_get_name(status));
if (sbuddy->mood && *sbuddy->mood) {
gchar *stripped = purple_markup_strip_html(sbuddy->mood);
gchar *escaped = g_markup_printf_escaped("%s", stripped);
purple_notify_user_info_add_pair_html(user_info, _("Message"), escaped);
g_free(stripped);
g_free(escaped);
}
if (sbuddy->display_name && *sbuddy->display_name) {
gchar *escaped = g_markup_printf_escaped("%s", sbuddy->display_name);
purple_notify_user_info_add_pair_html(user_info, "Alias", escaped);
g_free(escaped);
}
if (sbuddy->fullname && *sbuddy->fullname) {
gchar *escaped = g_markup_printf_escaped("%s", sbuddy->fullname);
purple_notify_user_info_add_pair_html(user_info, "Full Name", escaped);
g_free(escaped);
}
}
}
const gchar *
skypeweb_list_emblem(PurpleBuddy *buddy)
{
if (buddy != NULL) {
//SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy);
const gchar *buddy_name = purple_buddy_get_name(buddy);
if (buddy_name && SKYPEWEB_BUDDY_IS_BOT(buddy_name)) {
return "bot";
}
}
return NULL;
}
GList *
skypeweb_status_types(PurpleAccount *account)
{
GList *types = NULL;
PurpleStatusType *status;
status = purple_status_type_new_full(PURPLE_STATUS_OFFLINE, NULL, NULL, FALSE, FALSE, FALSE);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, SKYPEWEB_STATUS_ONLINE, _("Online"), TRUE, TRUE, FALSE, "message", "Mood", purple_value_new(PURPLE_TYPE_STRING), NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, SKYPEWEB_STATUS_AWAY, _("Away"), TRUE, TRUE, FALSE, "message", "Mood", purple_value_new(PURPLE_TYPE_STRING), NULL);
types = g_list_append(types, status);
// status = purple_status_type_new_with_attrs(PURPLE_STATUS_EXTENDED_AWAY, SKYPEWEB_STATUS_AWAY, _("Not Available"), TRUE, TRUE, FALSE, "message", "Mood", purple_value_new(PURPLE_TYPE_STRING), NULL);
// types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, SKYPEWEB_STATUS_BUSY, _("Do Not Disturb"), TRUE, TRUE, FALSE, "message", "Mood", purple_value_new(PURPLE_TYPE_STRING), NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, SKYPEWEB_STATUS_HIDDEN, _("Invisible"), TRUE, TRUE, FALSE, "message", "Mood", purple_value_new(PURPLE_TYPE_STRING), NULL);
types = g_list_append(types, status);
status = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE, SKYPEWEB_STATUS_OFFLINE, _("Offline"), TRUE, TRUE, FALSE, "message", "Mood", purple_value_new(PURPLE_TYPE_STRING), NULL);
types = g_list_append(types, status);
return types;
}
static GList *
skypeweb_chat_info(PurpleConnection *gc)
{
GList *m = NULL;
PurpleProtocolChatEntry *pce;
pce = g_new0(PurpleProtocolChatEntry, 1);
pce->label = _("Skype Name");
pce->identifier = "chatname";
pce->required = TRUE;
m = g_list_append(m, pce);
/*pce = g_new0(PurpleProtocolChatEntry, 1);
pce->label = _("Password");
pce->identifier = "password";
pce->required = FALSE;
m = g_list_append(m, pce);*/
return m;
}
static GHashTable *
skypeweb_chat_info_defaults(PurpleConnection *gc, const char *chatname)
{
GHashTable *defaults;
defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
if (chatname != NULL)
{
g_hash_table_insert(defaults, "chatname", g_strdup(chatname));
}
return defaults;
}
static gchar *
skypeweb_get_chat_name(GHashTable *data)
{
gchar *temp;
if (data == NULL)
return NULL;
temp = g_hash_table_lookup(data, "chatname");
if (temp == NULL)
return NULL;
return g_strdup(temp);
}
static void
skypeweb_join_chat(PurpleConnection *pc, GHashTable *data)
{
SkypeWebAccount *sa = purple_connection_get_protocol_data(pc);
gchar *chatname;
gchar *post;
GString *url;
PurpleChatConversation *chatconv;
chatname = (gchar *)g_hash_table_lookup(data, "chatname");
if (chatname == NULL)
{
return;
}
chatconv = purple_conversations_find_chat_with_account(chatname, sa->account);
if (chatconv != NULL && !purple_chat_conversation_has_left(chatconv)) {
purple_conversation_present(PURPLE_CONVERSATION(chatconv));
return;
}
url = g_string_new("/v1/threads/");
g_string_append_printf(url, "%s", purple_url_encode(chatname));
g_string_append(url, "/members/");
g_string_append_printf(url, "8:%s", purple_url_encode(sa->username));
/* Specifying the role does not seem to be required and often result in a users role being
* downgraded from admin to user
* post = "{\"role\":\"User\"}"; */
post = "{}";
skypeweb_post_or_get(sa, SKYPEWEB_METHOD_PUT | SKYPEWEB_METHOD_SSL, sa->messages_host, url->str, post, NULL, NULL, TRUE);
g_string_free(url, TRUE);
skypeweb_get_conversation_history(sa, chatname);
skypeweb_get_thread_users(sa, chatname);
chatconv = purple_serv_got_joined_chat(pc, g_str_hash(chatname), chatname);
purple_conversation_set_data(PURPLE_CONVERSATION(chatconv), "chatname", g_strdup(chatname));
purple_conversation_present(PURPLE_CONVERSATION(chatconv));
}
void
skypeweb_buddy_free(PurpleBuddy *buddy)
{
SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy);
if (sbuddy != NULL)
{
purple_buddy_set_protocol_data(buddy, NULL);
g_free(sbuddy->skypename);
g_free(sbuddy->fullname);
g_free(sbuddy->display_name);
g_free(sbuddy->avatar_url);
g_free(sbuddy->mood);
g_free(sbuddy);
}
}
void
skypeweb_fake_group_buddy(PurpleConnection *pc, const char *who, const char *old_group, const char *new_group)
{
// Do nothing to stop the remove+add behaviour
}
void
skypeweb_fake_group_rename(PurpleConnection *pc, const char *old_name, PurpleGroup *group, GList *moved_buddies)
{
// Do nothing to stop the remove+add behaviour
}
static GList *
skypeweb_node_menu(PurpleBlistNode *node)
{
GList *m = NULL;
PurpleMenuAction *act;
PurpleBuddy *buddy;
SkypeWebAccount *sa = NULL;
if(PURPLE_IS_BUDDY(node))
{
buddy = PURPLE_BUDDY(node);
if (purple_buddy_get_protocol_data(buddy)) {
SkypeWebBuddy *sbuddy = purple_buddy_get_protocol_data(buddy);
sa = sbuddy->sa;
}
if (sa == NULL) {
PurpleConnection *pc = purple_account_get_connection(purple_buddy_get_account(buddy));
sa = purple_connection_get_protocol_data(pc);
}
if (sa != NULL) {
act = purple_menu_action_new(_("Initiate _Chat"),
PURPLE_CALLBACK(skypeweb_initiate_chat_from_node),
sa, NULL);
m = g_list_append(m, act);
}
}
return m;
}
static gulong conversation_updated_signal = 0;
static gulong chat_conversation_typing_signal = 0;
static void
skypeweb_login(PurpleAccount *account)
{
PurpleConnection *pc = purple_account_get_connection(account);
SkypeWebAccount *sa = g_new0(SkypeWebAccount, 1);
PurpleConnectionFlags flags;
purple_connection_set_protocol_data(pc, sa);
flags = purple_connection_get_flags(pc);
flags |= PURPLE_CONNECTION_FLAG_HTML | PURPLE_CONNECTION_FLAG_NO_BGCOLOR | PURPLE_CONNECTION_FLAG_NO_FONTSIZE;
purple_connection_set_flags(pc, flags);
if (!SKYPEWEB_BUDDY_IS_MSN(purple_account_get_username(account))) {
sa->username = g_ascii_strdown(purple_account_get_username(account), -1);
}
sa->account = account;
sa->pc = pc;
sa->cookie_jar = purple_http_cookie_jar_new();
sa->sent_messages_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
sa->messages_host = g_strdup(SKYPEWEB_DEFAULT_MESSAGES_HOST);
sa->keepalive_pool = purple_http_keepalive_pool_new();
purple_http_keepalive_pool_set_limit_per_host(sa->keepalive_pool, SKYPEWEB_MAX_CONNECTIONS);
sa->conns = purple_http_connection_set_new();
if (purple_account_get_bool(account, "alt-login", FALSE)) {
skypeweb_begin_soapy_login(sa);
} else {
if (purple_account_get_string(account, "refresh-token", NULL) && purple_account_get_remember_password(account)) {
skypeweb_refresh_token_login(sa);
} else {
skypeweb_begin_oauth_login(sa);
}
}
if (!conversation_updated_signal) {
conversation_updated_signal = purple_signal_connect(purple_conversations_get_handle(), "conversation-updated", purple_connection_get_protocol(pc), PURPLE_CALLBACK(skypeweb_mark_conv_seen), NULL);
}
if (!chat_conversation_typing_signal) {
chat_conversation_typing_signal = purple_signal_connect(purple_conversations_get_handle(), "chat-conversation-typing", purple_connection_get_protocol(pc), PURPLE_CALLBACK(skypeweb_conv_send_typing), NULL);
}
}
static void
skypeweb_close(PurpleConnection *pc)
{
SkypeWebAccount *sa;
GSList *buddies;
g_return_if_fail(pc != NULL);
#if !PURPLE_VERSION_CHECK(3, 0, 0)
purple_connection_set_state(pc, PURPLE_CONNECTION_DISCONNECTING);
#endif
sa = purple_connection_get_protocol_data(pc);
g_return_if_fail(sa != NULL);
g_source_remove(sa->authcheck_timeout);
g_source_remove(sa->poll_timeout);
g_source_remove(sa->watchdog_timeout);
skypeweb_logout(sa);
purple_debug_info("skypeweb", "destroying incomplete connections\n");
purple_http_connection_set_destroy(sa->conns);
purple_http_conn_cancel_all(pc);
purple_http_keepalive_pool_unref(sa->keepalive_pool);
purple_http_cookie_jar_unref(sa->cookie_jar);
buddies = purple_blist_find_buddies(sa->account, NULL);
while (buddies != NULL) {
PurpleBuddy *buddy = buddies->data;
skypeweb_buddy_free(buddy);
purple_buddy_set_protocol_data(buddy, NULL);
buddies = g_slist_delete_link(buddies, buddies);
}
g_hash_table_destroy(sa->sent_messages_hash);
g_free(sa->vdms_token);
g_free(sa->messages_host);
g_free(sa->skype_token);
g_free(sa->registration_token);
g_free(sa->endpoint);
g_free(sa->primary_member_name);
g_free(sa->self_display_name);
g_free(sa->username);
g_free(sa);
}
gboolean
skypeweb_offline_message(const PurpleBuddy *buddy)
{
return TRUE;
}
static PurpleCmdRet
skypeweb_cmd_list(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
{
purple_roomlist_show_with_account(purple_conversation_get_account(conv));
return PURPLE_CMD_RET_OK;
}
static PurpleCmdRet
skypeweb_cmd_leave(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
{
PurpleConnection *pc = NULL;
int id = -1;
SkypeWebAccount *sa;
pc = purple_conversation_get_connection(conv);
id = purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv));
if (pc == NULL || id == -1)
return PURPLE_CMD_RET_FAILED;
sa = purple_connection_get_protocol_data(pc);
if (sa == NULL)
return PURPLE_CMD_RET_FAILED;
skypeweb_chat_kick(pc, id, sa->username);
return PURPLE_CMD_RET_OK;
}
static PurpleCmdRet
skypeweb_cmd_kick(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
{
PurpleConnection *pc = NULL;
int id = -1;
pc = purple_conversation_get_connection(conv);
id = purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv));
if (pc == NULL || id == -1)
return PURPLE_CMD_RET_FAILED;
skypeweb_chat_kick(pc, id, args[0]);
return PURPLE_CMD_RET_OK;
}
static PurpleCmdRet
skypeweb_cmd_invite(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
{
PurpleConnection *pc = NULL;
int id = -1;
pc = purple_conversation_get_connection(conv);
id = purple_chat_conversation_get_id(PURPLE_CHAT_CONVERSATION(conv));
if (pc == NULL || id == -1)
return PURPLE_CMD_RET_FAILED;
skypeweb_chat_invite(pc, id, NULL, args[0]);
return PURPLE_CMD_RET_OK;
}
static PurpleCmdRet
skypeweb_cmd_topic(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data)
{
PurpleConnection *pc = NULL;
PurpleChatConversation *chat;
int id = -1;
pc = purple_conversation_get_connection(conv);
chat = PURPLE_CHAT_CONVERSATION(conv);
id = purple_chat_conversation_get_id(chat);
if (pc == NULL || id == -1)
return PURPLE_CMD_RET_FAILED;
if (!args || !args[0]) {
gchar *buf;
const gchar *topic = purple_chat_conversation_get_topic(chat);
if (topic) {
gchar *tmp, *tmp2;
tmp = g_markup_escape_text(topic, -1);
tmp2 = purple_markup_linkify(tmp);
buf = g_strdup_printf(_("current topic is: %s"), tmp2);
g_free(tmp);
g_free(tmp2);
} else {
buf = g_strdup(_("No topic is set"));
}
purple_conversation_write_system_message(conv, buf, PURPLE_MESSAGE_NO_LOG);
g_free(buf);
return PURPLE_CMD_RET_OK;
}
skypeweb_chat_set_topic(pc, id, args[0]);
return PURPLE_CMD_RET_OK;
}
/******************************************************************************/
/* Plugin functions */
/******************************************************************************/
static gboolean
skypeweb_uri_handler(const char *proto, const char *cmd, GHashTable *params)
{
PurpleAccount *account;
PurpleConnection *pc;
if (!g_str_equal(proto, "skype"))
return FALSE;
/*skype uri's:
skype: //does nothing
skype:{buddyname} //open im with {buddyname}
skype:{buddynames}?chat //open multi-user chat with {buddynames}
skype:?chat&blob={blob id} //open public multi-user chat with the blob id of {blob id}
skype:?chat&id={chat id} //open multi-user chat with the id of {chat id}
skype:{buddyname}?add //add user to buddy list
skype:{buddyname}?userinfo //get buddy's info
skype:{buddynames}?call //call {buddynames}
skype:{buddyname}?voicemail //send a voice mail message
skype:{buddyname}?sendfile //send a file
*/
account = find_acct(SKYPEWEB_PLUGIN_ID, g_hash_table_lookup(params, "account"));
pc = purple_account_get_connection(account);
if (g_hash_table_lookup(params, "chat")) {
if (cmd && *cmd) {
//there'll be a bunch of usernames, seperated by semi-colon
if (strchr(cmd, ';')) {
gchar **users = g_strsplit_set(cmd, ";", -1);
skypeweb_initiate_chat(purple_connection_get_protocol_data(pc), users[0]);
//TODO the other users
g_strfreev(users);
} else {
PurpleIMConversation *imconv;
imconv = purple_conversations_find_im_with_account(cmd, account);
if (!imconv) {
imconv = purple_im_conversation_new(account, cmd);
}
purple_conversation_present(PURPLE_CONVERSATION(imconv));
}
} else {
//probably a public multi-user chat?
GHashTable *chatinfo = NULL;
if (g_hash_table_lookup(params, "id")) {
chatinfo = skypeweb_chat_info_defaults(pc, g_hash_table_lookup(params, "id"));
} else if (g_hash_table_lookup(params, "blob")) {
chatinfo = skypeweb_chat_info_defaults(pc, g_hash_table_lookup(params, "blob"));
}
if (chatinfo != NULL) {
skypeweb_join_chat(pc, chatinfo);
g_hash_table_destroy(chatinfo);
}
}
} else if (g_hash_table_lookup(params, "add")) {
purple_blist_request_add_buddy(account, cmd, "Skype", g_hash_table_lookup(params, "displayname"));
return TRUE;
} else if (g_hash_table_lookup(params, "call")) {
} else if (g_hash_table_lookup(params, "userinfo")) {
skypeweb_get_info(pc, cmd);
return TRUE;
} else if (g_hash_table_lookup(params, "voicemail")) {
} else if (g_hash_table_lookup(params, "sendfile")) {
} else if (strlen(cmd)) {
//supposed to be the same as call?
}
//we don't know how to handle this
return FALSE;
}
#if PURPLE_VERSION_CHECK(3, 0, 0)
typedef struct _SkypeWebProtocol
{
PurpleProtocol parent;
} SkypeWebProtocol;
typedef struct _SkypeWebProtocolClass
{
PurpleProtocolClass parent_class;
} SkypeWebProtocolClass;
G_MODULE_EXPORT GType skypeweb_protocol_get_type(void);
#define SKYPEWEB_TYPE_PROTOCOL (skypeweb_protocol_get_type())
#define SKYPEWEB_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SKYPEWEB_TYPE_PROTOCOL, SkypeWebProtocol))
#define SKYPEWEB_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SKYPEWEB_TYPE_PROTOCOL, SkypeWebProtocolClass))
#define SKYPEWEB_IS_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SKYPEWEB_TYPE_PROTOCOL))
#define SKYPEWEB_IS_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SKYPEWEB_TYPE_PROTOCOL))
#define SKYPEWEB_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SKYPEWEB_TYPE_PROTOCOL, SkypeWebProtocolClass))
static PurpleProtocol *skypeweb_protocol;
#else
// Normally set in core.c in purple3
void _purple_socket_init(void);
void _purple_socket_uninit(void);
#endif
static gboolean
plugin_load(PurplePlugin *plugin
#if PURPLE_VERSION_CHECK(3, 0, 0)
, GError **error
#endif
)
{
#if !PURPLE_VERSION_CHECK(3, 0, 0)
_purple_socket_init();
purple_http_init();
#endif
//leave
purple_cmd_register("leave", "", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
SKYPEWEB_PLUGIN_ID, skypeweb_cmd_leave,
_("leave: Leave the group chat"), NULL);
//kick
purple_cmd_register("kick", "s", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY,
SKYPEWEB_PLUGIN_ID, skypeweb_cmd_kick,
_("kick <user>: Kick a user from the group chat."),
NULL);
//add
purple_cmd_register("add", "s", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY,
SKYPEWEB_PLUGIN_ID, skypeweb_cmd_invite,
_("add <user>: Add a user to the group chat."),
NULL);
//topic
purple_cmd_register("topic", "s", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS,
SKYPEWEB_PLUGIN_ID, skypeweb_cmd_topic,
_("topic [<new topic>]: View or change the topic"),
NULL);
/*
//call, as in call person
//kickban
purple_cmd_register("kickban", "s", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY,
SKYPEWEB_PLUGIN_ID, skypeweb_cmd_kickban,
_("kickban <user> [room]: Kick and ban a user from the room."),
NULL);
//setrole
purple_cmd_register("setrole", "ss", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY,
SKYPEWEB_PLUGIN_ID, skypeweb_cmd_setrole,
_("setrole <user> <MASTER | USER | ADMIN>: Change the role of a user."),
NULL);
*/
purple_cmd_register("list", "", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_CHAT |
PURPLE_CMD_FLAG_PROTOCOL_ONLY | PURPLE_CMD_FLAG_IM,
SKYPEWEB_PLUGIN_ID, skypeweb_cmd_list,
_("list: Display a list of multi-chat group chats you are in."),
NULL);
purple_signal_connect(purple_get_core(), "uri-handler", plugin, PURPLE_CALLBACK(skypeweb_uri_handler), NULL);
return TRUE;
}
static gboolean
plugin_unload(PurplePlugin *plugin
#if PURPLE_VERSION_CHECK(3, 0, 0)
, GError **error
#endif
)
{
#if !PURPLE_VERSION_CHECK(3, 0, 0)
_purple_socket_uninit();
purple_http_uninit();
#endif
purple_signals_disconnect_by_handle(plugin);
return TRUE;
}
static GList *
skypeweb_actions(
#if !PURPLE_VERSION_CHECK(3, 0, 0)
PurplePlugin *plugin, gpointer context
#else
PurpleConnection *pc
#endif
)
{
GList *m = NULL;
PurpleProtocolAction *act;
act = purple_protocol_action_new(_("Search for friends..."), skypeweb_search_users);
m = g_list_append(m, act);
act = purple_protocol_action_new(_("People you might know..."), skypeweb_contact_suggestions);
m = g_list_append(m, act);
return m;
}
#if !PURPLE_VERSION_CHECK(2, 8, 0)
# define OPT_PROTO_INVITE_MESSAGE 0x00000800
#endif
#if !PURPLE_VERSION_CHECK(3, 0, 0)
static void
plugin_init(PurplePlugin *plugin)
{
PurplePluginInfo *info = g_new0(PurplePluginInfo, 1);
PurplePluginProtocolInfo *prpl_info = g_new0(PurplePluginProtocolInfo, 1);
#endif
#if PURPLE_VERSION_CHECK(3, 0, 0)
static void
skypeweb_protocol_init(PurpleProtocol *prpl_info)
{
PurpleProtocol *info = prpl_info;
#endif
PurpleAccountOption *typing_type1, *typing_type2, *alt_login;
PurpleBuddyIconSpec icon_spec = {"jpeg", 0, 0, 96, 96, 0, PURPLE_ICON_SCALE_DISPLAY};
//PurpleProtocol
info->id = SKYPEWEB_PLUGIN_ID;
info->name = "Skype (HTTP)";
prpl_info->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_INVITE_MESSAGE /*| OPT_PROTO_IM_IMAGE*/;
typing_type1 = purple_account_option_bool_new(N_("Show 'Typing' status as system message in chat window."), "show-typing-as-text", FALSE);
typing_type2 = purple_account_option_bool_new(N_("Show 'Typing' status with 'Voice' icon near buddy name."), "show-typing-as-icon", FALSE);
alt_login = purple_account_option_bool_new(N_("Use alternative login method"), "alt-login", TRUE);
#if !PURPLE_VERSION_CHECK(3, 0, 0)
prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, typing_type1);
prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, typing_type2);
prpl_info->protocol_options = g_list_append(prpl_info->protocol_options, alt_login);
prpl_info->icon_spec = icon_spec;
#else
prpl_info->account_options = g_list_append(prpl_info->account_options, typing_type1);
prpl_info->account_options = g_list_append(prpl_info->account_options, typing_type2);
prpl_info->account_options = g_list_append(prpl_info->account_options, alt_login);
prpl_info->icon_spec = &icon_spec;
#endif
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_class_init(PurpleProtocolClass *prpl_info)
{
#endif
//PurpleProtocolClass
prpl_info->login = skypeweb_login;
prpl_info->close = skypeweb_close;
prpl_info->status_types = skypeweb_status_types;
prpl_info->list_icon = skypeweb_list_icon;
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_client_iface_init(PurpleProtocolClientIface *prpl_info)
{
PurpleProtocolClientIface *info = prpl_info;
#endif
//PurpleProtocolClientIface
#if !PURPLE_VERSION_CHECK(3, 0, 0)
info->actions = skypeweb_actions;
#else
info->get_actions = skypeweb_actions;
#endif
prpl_info->list_emblem = skypeweb_list_emblem;
prpl_info->status_text = skypeweb_status_text;
prpl_info->tooltip_text = skypeweb_tooltip_text;
prpl_info->blist_node_menu = skypeweb_node_menu;
prpl_info->buddy_free = skypeweb_buddy_free;
prpl_info->normalize = purple_normalize_nocase;
prpl_info->offline_message = skypeweb_offline_message;
prpl_info->get_account_text_table = NULL; // skypeweb_get_account_text_table;
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_server_iface_init(PurpleProtocolServerIface *prpl_info)
{
#endif
//PurpleProtocolServerIface
prpl_info->get_info = skypeweb_get_info;
prpl_info->set_status = skypeweb_set_status;
prpl_info->set_idle = skypeweb_set_idle;
#if !PURPLE_VERSION_CHECK(3, 0, 0)
prpl_info->add_buddy = skypeweb_add_buddy;
#else
prpl_info->add_buddy = skypeweb_add_buddy_with_invite;
#endif
prpl_info->remove_buddy = skypeweb_buddy_remove;
prpl_info->group_buddy = skypeweb_fake_group_buddy;
prpl_info->rename_group = skypeweb_fake_group_rename;
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_im_iface_init(PurpleProtocolIMIface *prpl_info)
{
#endif
//PurpleProtocolIMIface
#if !PURPLE_VERSION_CHECK(3, 0, 0)
prpl_info->send_im = skypeweb_send_im;
#else
prpl_info->send = skypeweb_send_im;
#endif
prpl_info->send_typing = skypeweb_send_typing;
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_chat_iface_init(PurpleProtocolChatIface *prpl_info)
{
#endif
//PurpleProtocolChatIface
#if !PURPLE_VERSION_CHECK(3, 0, 0)
prpl_info->chat_info = skypeweb_chat_info;
prpl_info->chat_info_defaults = skypeweb_chat_info_defaults;
prpl_info->join_chat = skypeweb_join_chat;
prpl_info->get_chat_name = skypeweb_get_chat_name;
prpl_info->chat_invite = skypeweb_chat_invite;
prpl_info->chat_leave = NULL; //skypeweb_chat_fake_leave;
prpl_info->chat_send = skypeweb_chat_send;
prpl_info->set_chat_topic = skypeweb_chat_set_topic;
#else
prpl_info->info = skypeweb_chat_info;
prpl_info->info_defaults = skypeweb_chat_info_defaults;
prpl_info->join = skypeweb_join_chat;
prpl_info->get_name = skypeweb_get_chat_name;
prpl_info->invite = skypeweb_chat_invite;
prpl_info->leave = NULL; //skypeweb_chat_fake_leave;
prpl_info->send = skypeweb_chat_send;
prpl_info->set_topic = skypeweb_chat_set_topic;
#endif
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_privacy_iface_init(PurpleProtocolPrivacyIface *prpl_info)
{
#endif
//PurpleProtocolPrivacyIface
prpl_info->add_deny = skypeweb_buddy_block;
prpl_info->rem_deny = skypeweb_buddy_unblock;
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_xfer_iface_init(PurpleProtocolXferInterface *prpl_info)
{
#endif
//PurpleProtocolXferInterface
prpl_info->new_xfer = skypeweb_new_xfer;
prpl_info->send_file = skypeweb_send_file;
#if !PURPLE_VERSION_CHECK(3, 0, 0)
prpl_info->can_receive_file = skypeweb_can_receive_file;
#else
prpl_info->can_receive = skypeweb_can_receive_file;
#endif
#if PURPLE_VERSION_CHECK(3, 0, 0)
}
static void
skypeweb_protocol_roomlist_iface_init(PurpleProtocolRoomlistIface *prpl_info)
{
#endif
//PurpleProtocolRoomlistIface
#if !PURPLE_VERSION_CHECK(3, 0, 0)
prpl_info->roomlist_get_list = skypeweb_roomlist_get_list;
#else
prpl_info->get_list = skypeweb_roomlist_get_list;
#endif
#if !PURPLE_VERSION_CHECK(3, 0, 0)
// Plugin info
info->magic = PURPLE_PLUGIN_MAGIC;
info->major_version = 2;
info->minor_version = MIN(PURPLE_MINOR_VERSION, 8);
info->type = PURPLE_PLUGIN_PROTOCOL;
info->priority = PURPLE_PRIORITY_DEFAULT;
info->version = SKYPEWEB_PLUGIN_VERSION;
info->summary = N_("Skype for Web Protocol Plugin");
info->description = N_("Skype for Web Protocol Plugin");
info->author = "Eion Robb ";
info->homepage = "http://github.com/EionRobb/skype4pidgin";
info->load = plugin_load;
info->unload = plugin_unload;
info->extra_info = prpl_info;
// Protocol info
#if PURPLE_MINOR_VERSION >= 5
prpl_info->struct_size = sizeof(PurplePluginProtocolInfo);
#endif
#if PURPLE_MINOR_VERSION >= 8
prpl_info->add_buddy_with_invite = skypeweb_add_buddy_with_invite;
#endif
plugin->info = info;
#endif
}
#if PURPLE_VERSION_CHECK(3, 0, 0)
PURPLE_DEFINE_TYPE_EXTENDED(
SkypeWebProtocol, skypeweb_protocol, PURPLE_TYPE_PROTOCOL, 0,
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CLIENT_IFACE,
skypeweb_protocol_client_iface_init)
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_SERVER_IFACE,
skypeweb_protocol_server_iface_init)
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_IM_IFACE,
skypeweb_protocol_im_iface_init)
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_CHAT_IFACE,
skypeweb_protocol_chat_iface_init)
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_PRIVACY_IFACE,
skypeweb_protocol_privacy_iface_init)
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_ROOMLIST_IFACE,
skypeweb_protocol_roomlist_iface_init)
PURPLE_IMPLEMENT_INTERFACE_STATIC(PURPLE_TYPE_PROTOCOL_XFER,
skypeweb_protocol_xfer_iface_init)
);
static gboolean
libpurple3_plugin_load(PurplePlugin *plugin, GError **error)
{
skypeweb_protocol_register_type(plugin);
skypeweb_protocol = purple_protocols_add(SKYPEWEB_TYPE_PROTOCOL, error);
if (!skypeweb_protocol)
return FALSE;
return plugin_load(plugin, error);
}
static gboolean
libpurple3_plugin_unload(PurplePlugin *plugin, GError **error)
{
if (!plugin_unload(plugin, error))
return FALSE;
if (!purple_protocols_remove(skypeweb_protocol, error))
return FALSE;
return TRUE;
}
static PurplePluginInfo *
plugin_query(GError **error)
{
return purple_plugin_info_new(
"id", SKYPEWEB_PLUGIN_ID,
"name", "SkypeWeb Protocol",
"version", SKYPEWEB_PLUGIN_VERSION,
"category", N_("Protocol"),
"summary", N_("SkypeWeb Protocol Plugin"),
"description", N_("SkypeWeb Protocol Plugin"),
"website", "http://github.com/EionRobb/skype4pidgin",
"abi-version", PURPLE_ABI_VERSION,
"flags", PURPLE_PLUGIN_INFO_FLAGS_INTERNAL |
PURPLE_PLUGIN_INFO_FLAGS_AUTO_LOAD,
NULL
);
}
PURPLE_PLUGIN_INIT(skypeweb, plugin_query, libpurple3_plugin_load, libpurple3_plugin_unload);
#else
static PurplePluginInfo aLovelyBunchOfCoconuts;
PURPLE_INIT_PLUGIN(skypeweb, plugin_init, aLovelyBunchOfCoconuts);
#endif