pidgin/purple-plugin-pack
Clone
Summary
Browse
Changes
Graph
Add the turtles target to keep the foot clan at bay
default
tip
13 months ago, Gary Kramlich
63ad7e4f10b4
Add the turtles target to keep the foot clan at bay
Testing Done:
Ran `ninja turtles` and verified it worked correctly.
Reviewed at https://reviews.imfreedom.org/r/2409/
/*
* ning_chat.c
* pidgin-ning
*
* Created by MyMacSpace on 6/08/09.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include
"ning_chat.h"
//list buddies
//send message to chat
//send whisper
//poll for messages
//fetch chat history
//join chat
/*
void (*chat_leave)(PurpleConnection *, int id);
void (*chat_whisper)(PurpleConnection *, int id, const char *who, const char *message);
int (*chat_send)(PurpleConnection *, int id, const char *message, PurpleMessageFlags flags);
void (*join_chat)(PurpleConnection *, GHashTable *components);
PurpleConversation* purple_find_chat(const PurpleConnection *gc, int id);
*/
gint64
ning_time_kludge
(
gint
initial_time
)
{
if
(
sizeof
(
gint
)
>=
sizeof
(
gint64
))
return
initial_time
;
gint64
now_millis
=
(
gint64
)
time
(
NULL
);
now_millis
*=
1000
;
now_millis
&=
0xFFFFFFFF00000000LL
;
gint64
final_time
=
now_millis
|
((
guint
)
initial_time
);
return
final_time
;
}
void
ning_chat_messages_cb
(
NingAccount
*
na
,
gchar
*
response
,
gsize
len
,
gpointer
userdata
)
{
NingChat
*
chat
;
JsonObject
*
obj
;
JsonArray
*
array
;
JsonObject
*
msgobj
;
const
gchar
*
type
;
const
gchar
*
body
;
gint
date
;
JsonObject
*
sender
;
const
gchar
*
senderId
;
PurpleBuddy
*
buddy
;
PurpleGroup
*
group
;
guint
i
;
guint64
time_kludge
;
chat
=
userdata
;
purple_debug_info
(
"ning"
,
"ning_chat_messages_cb: %s
\n
"
,
response
?
response
:
"(null)"
);
obj
=
ning_json_parse
(
response
,
len
);
if
(
json_object_has_member
(
obj
,
"hash"
))
{
g_free
(
chat
->
ning_hash
);
chat
->
ning_hash
=
g_strdup
(
json_node_get_string
(
json_object_get_member
(
obj
,
"hash"
)));
}
array
=
json_node_get_array
(
json_object_get_member
(
obj
,
"messages"
));
for
(
i
=
0
;
i
<
json_array_get_length
(
array
);
i
++
)
{
msgobj
=
json_node_get_object
(
json_array_get_element
(
array
,
i
));
//type (message or private)
//body, date, roomId, targetId, sender(obj)
type
=
json_node_get_string
(
json_object_get_member
(
msgobj
,
"type"
));
body
=
json_node_get_string
(
json_object_get_member
(
msgobj
,
"body"
));
date
=
json_node_get_int
(
json_object_get_member
(
msgobj
,
"date"
));
sender
=
json_node_get_object
(
json_object_get_member
(
msgobj
,
"sender"
));
senderId
=
json_node_get_string
(
json_object_get_member
(
sender
,
"ningId"
));
//Check that they're on the buddy list
buddy
=
purple_find_buddy
(
na
->
account
,
senderId
);
if
(
!
buddy
)
{
//They aren't, so lets fake it
buddy
=
purple_buddy_new
(
na
->
account
,
senderId
,
json_node_get_string
(
json_object_get_member
(
sender
,
"name"
)));
group
=
purple_find_group
(
NING_TEMP_GROUP_NAME
);
if
(
!
group
)
{
group
=
purple_group_new
(
NING_TEMP_GROUP_NAME
);
purple_blist_add_group
(
group
,
NULL
);
purple_blist_node_set_flags
(
&
group
->
node
,
PURPLE_BLIST_NODE_FLAG_NO_SAVE
);
}
purple_blist_add_buddy
(
buddy
,
NULL
,
group
,
NULL
);
purple_blist_node_set_flags
(
&
buddy
->
node
,
PURPLE_BLIST_NODE_FLAG_NO_SAVE
);
}
time_kludge
=
ning_time_kludge
(
date
);
if
(
g_str_equal
(
type
,
"message"
))
{
serv_got_chat_in
(
na
->
pc
,
chat
->
purple_id
,
senderId
,
PURPLE_MESSAGE_RECV
,
body
,
time_kludge
);
}
else
if
(
g_str_equal
(
type
,
"private"
))
{
serv_got_chat_in
(
na
->
pc
,
chat
->
purple_id
,
senderId
,
PURPLE_MESSAGE_RECV
|
PURPLE_MESSAGE_WHISPER
,
body
,
time_kludge
);
}
else
{
purple_debug_info
(
"ning"
,
"unknown message type: %s
\n
"
,
type
);
}
}
json_object_unref
(
obj
);
}
gboolean
ning_chat_get_history
(
NingChat
*
chat
)
{
NingAccount
*
na
;
gchar
*
url
;
gchar
*
encoded_hash
;
gchar
*
encoded_app
;
gchar
*
encoded_id
;
gchar
*
encoded_token
;
gchar
*
encoded_room
;
na
=
chat
->
na
;
encoded_hash
=
g_strdup
(
purple_url_encode
(
chat
->
ning_hash
));
encoded_app
=
g_strdup
(
purple_url_encode
(
na
->
ning_app
));
encoded_id
=
g_strdup
(
purple_url_encode
(
na
->
ning_id
));
encoded_token
=
g_strdup
(
purple_url_encode
(
na
->
chat_token
));
encoded_room
=
g_strdup
(
purple_url_encode
(
chat
->
roomId
));
url
=
g_strdup_printf
(
"/xn/groupchat/list?h=%s&a=%s&i=%s&t=%s&r=%s"
,
encoded_hash
,
encoded_app
,
encoded_id
,
encoded_token
,
encoded_room
);
ning_post_or_get
(
na
,
NING_METHOD_GET
,
na
->
chat_domain
,
url
,
NULL
,
ning_chat_messages_cb
,
chat
,
FALSE
);
g_free
(
url
);
g_free
(
encoded_room
);
g_free
(
encoded_token
);
g_free
(
encoded_id
);
g_free
(
encoded_app
);
g_free
(
encoded_hash
);
return
FALSE
;
}
void
ning_chat_get_users_cb
(
NingAccount
*
na
,
gchar
*
response
,
gsize
len
,
gpointer
userdata
)
{
NingChat
*
chat
;
JsonObject
*
obj
;
JsonArray
*
array
;
JsonObject
*
userobj
;
int
i
;
const
gchar
*
ningId
;
const
gchar
*
name
;
//const gchar *iconUrl;
gboolean
isAdmin
;
PurpleConversation
*
conv
;
// PurpleBuddy *buddy;
PurpleConvChatBuddy
*
cbuddy
;
PurpleConversationUiOps
*
uiops
;
purple_debug_info
(
"ning"
,
"chat users: %s
\n
"
,
response
?
response
:
"(null)"
);
chat
=
userdata
;
obj
=
ning_json_parse
(
response
,
len
);
if
(
json_object_has_member
(
obj
,
"hash"
))
{
g_free
(
chat
->
ning_hash
);
chat
->
ning_hash
=
g_strdup
(
json_node_get_string
(
json_object_get_member
(
obj
,
"hash"
)));
}
conv
=
purple_find_chat
(
na
->
pc
,
chat
->
purple_id
);
uiops
=
purple_conversation_get_ui_ops
(
conv
);
array
=
json_node_get_array
(
json_object_get_member
(
obj
,
"expired"
));
for
(
i
=
0
;
i
<
json_array_get_length
(
array
);
i
++
)
{
ningId
=
json_node_get_string
(
json_array_get_element
(
array
,
i
));
purple_conv_chat_remove_user
(
PURPLE_CONV_CHAT
(
conv
),
ningId
,
NULL
);
}
array
=
json_node_get_array
(
json_object_get_member
(
obj
,
"users"
));
if
(
array
&&
json_array_get_length
(
array
)
>
0
)
{
purple_conv_chat_clear_users
(
PURPLE_CONV_CHAT
(
conv
));
}
for
(
i
=
0
;
i
<
json_array_get_length
(
array
);
i
++
)
{
userobj
=
json_node_get_object
(
json_array_get_element
(
array
,
i
));
//isNC, iconUrl, name, ningId, isAdmin
ningId
=
json_node_get_string
(
json_object_get_member
(
userobj
,
"ningId"
));
name
=
json_node_get_string
(
json_object_get_member
(
userobj
,
"name"
));
isAdmin
=
json_node_get_boolean
(
json_object_get_member
(
userobj
,
"isAdmin"
));
if
(
!
purple_conv_chat_find_user
(
PURPLE_CONV_CHAT
(
conv
),
ningId
))
{
purple_conv_chat_add_user
(
PURPLE_CONV_CHAT
(
conv
),
ningId
,
NULL
,
isAdmin
?
PURPLE_CBFLAGS_OP
:
PURPLE_CBFLAGS_NONE
,
FALSE
);
}
cbuddy
=
purple_conv_chat_cb_find
(
PURPLE_CONV_CHAT
(
conv
),
ningId
);
if
(
cbuddy
)
{
g_free
(
cbuddy
->
alias
);
cbuddy
->
alias
=
g_strdup
(
name
);
}
//Refresh the buddy
if
(
uiops
&&
uiops
->
chat_rename_user
)
{
purple_debug_info
(
"ning"
,
"try rename user %s to %s
\n
"
,
ningId
,
name
);
uiops
->
chat_rename_user
(
conv
,
ningId
,
ningId
,
name
);
}
else
if
(
uiops
&&
uiops
->
chat_update_user
)
{
purple_debug_info
(
"ning"
,
"try update user %s
\n
"
,
ningId
);
uiops
->
chat_update_user
(
conv
,
ningId
);
}
}
json_object_unref
(
obj
);
}
gboolean
ning_chat_get_users
(
NingChat
*
chat
)
{
NingAccount
*
na
;
gchar
*
url
;
gchar
*
encoded_hash
;
gchar
*
encoded_app
;
gchar
*
encoded_id
;
gchar
*
encoded_token
;
gchar
*
encoded_room
;
na
=
chat
->
na
;
encoded_hash
=
g_strdup
(
purple_url_encode
(
chat
->
ning_hash
));
encoded_app
=
g_strdup
(
purple_url_encode
(
na
->
ning_app
));
encoded_id
=
g_strdup
(
purple_url_encode
(
na
->
ning_id
));
encoded_token
=
g_strdup
(
purple_url_encode
(
na
->
chat_token
));
encoded_room
=
g_strdup
(
purple_url_encode
(
chat
->
roomId
));
url
=
g_strdup_printf
(
"/xn/presence/list?h=%s&a=%s&i=%s&t=%s&r=%s"
,
encoded_hash
,
encoded_app
,
encoded_id
,
encoded_token
,
encoded_room
);
ning_post_or_get
(
na
,
NING_METHOD_GET
,
na
->
chat_domain
,
url
,
NULL
,
ning_chat_get_users_cb
,
chat
,
FALSE
);
g_free
(
url
);
g_free
(
encoded_room
);
g_free
(
encoded_token
);
g_free
(
encoded_id
);
g_free
(
encoded_app
);
g_free
(
encoded_hash
);
return
TRUE
;
}
gboolean
ning_chat_poll_messages
(
NingChat
*
chat
)
{
NingAccount
*
na
;
gchar
*
url
;
gchar
*
encoded_app
;
gchar
*
encoded_id
;
gchar
*
encoded_token
;
gchar
*
encoded_room
;
na
=
chat
->
na
;
encoded_app
=
g_strdup
(
purple_url_encode
(
na
->
ning_app
));
encoded_id
=
g_strdup
(
purple_url_encode
(
na
->
ning_id
));
encoded_token
=
g_strdup
(
purple_url_encode
(
na
->
chat_token
));
encoded_room
=
g_strdup
(
purple_url_encode
(
chat
->
roomId
));
url
=
g_strdup_printf
(
"/xn/groupchat/poll?a=%s&i=%s&t=%s&r=%s"
,
encoded_app
,
encoded_id
,
encoded_token
,
encoded_room
);
ning_post_or_get
(
na
,
NING_METHOD_GET
,
na
->
chat_domain
,
url
,
NULL
,
ning_chat_messages_cb
,
chat
,
FALSE
);
g_free
(
url
);
g_free
(
encoded_room
);
g_free
(
encoded_token
);
g_free
(
encoded_id
);
g_free
(
encoded_app
);
return
TRUE
;
}
void
ning_chat_cb
(
NingAccount
*
na
,
gchar
*
response
,
gsize
len
,
gpointer
userdata
)
{
purple_debug_info
(
"ning"
,
"ning_chat_cb: %s
\n
"
,
response
?
response
:
"(null)"
);
}
void
ning_chat_whisper
(
PurpleConnection
*
pc
,
int
id
,
const
char
*
who
,
const
char
*
message
)
{
NingAccount
*
na
;
gchar
*
stripped
;
PurpleConversation
*
conv
;
gchar
*
postdata
;
gchar
*
message_json
;
gchar
*
sender
;
gchar
*
message_escaped
;
gchar
*
ning_id_escaped
;
gchar
*
token_escaped
;
gchar
*
room_escaped
;
gchar
*
app_escaped
;
purple_debug_info
(
"ning"
,
"chat whisper %s %s
\n
"
,
who
,
message
);
na
=
pc
->
proto_data
;
conv
=
purple_find_chat
(
pc
,
id
);
app_escaped
=
g_strdup
(
purple_url_encode
(
na
->
ning_app
));
token_escaped
=
g_strdup
(
purple_url_encode
(
na
->
xg_token
));
room_escaped
=
g_strdup
(
purple_url_encode
(
conv
->
name
));
ning_id_escaped
=
g_strdup
(
purple_url_encode
(
na
->
ning_id
));
sender
=
build_user_json
(
na
);
stripped
=
purple_markup_strip_html
(
message
);
if
(
who
!=
NULL
)
{
message_json
=
g_strdup_printf
(
"{
\"
roomId
\"
:
\"
%s
\"
,
\"
type
\"
:
\"
private
\"
,
\"
targetId
\"
:
\"
%s
\"
,
\"
body
\"
:
\"
%s
\"
,
\"
sender
\"
:%s }"
,
conv
->
name
,
who
,
stripped
,
sender
);
}
else
{
message_json
=
g_strdup_printf
(
"{
\"
roomId
\"
:
\"
%s
\"
,
\"
type
\"
:
\"
message
\"
,
\"
targetId
\"
:null,
\"
body
\"
:
\"
%s
\"
,
\"
sender
\"
:%s }"
,
conv
->
name
,
stripped
,
sender
);
}
message_escaped
=
g_strdup
(
purple_url_encode
(
message_json
));
postdata
=
g_strdup_printf
(
"a=%s&i=%s&t=%s&r=%s&message=%s"
,
app_escaped
,
ning_id_escaped
,
token_escaped
,
room_escaped
,
message_escaped
);
ning_post_or_get
(
na
,
NING_METHOD_POST
,
na
->
chat_domain
,
"/xn/groupchat/publish"
,
postdata
,
ning_chat_cb
,
conv
,
FALSE
);
g_free
(
sender
);
g_free
(
postdata
);
g_free
(
message_escaped
);
g_free
(
message_json
);
g_free
(
stripped
);
g_free
(
app_escaped
);
g_free
(
ning_id_escaped
);
g_free
(
token_escaped
);
g_free
(
room_escaped
);
}
int
ning_send_im
(
PurpleConnection
*
pc
,
const
char
*
who
,
const
char
*
message
,
PurpleMessageFlags
flags
)
{
PurpleConversation
*
conv
;
GList
*
chats
;
PurpleConvChat
*
chat
;
gint
chat_id
;
if
(
flags
!=
PURPLE_MESSAGE_SEND
)
return
-1
;
chats
=
purple_get_chats
();
for
(;
chats
;
chats
=
chats
->
next
)
{
conv
=
chats
->
data
;
chat
=
PURPLE_CONV_CHAT
(
conv
);
if
(
purple_conv_chat_find_user
(
chat
,
who
))
{
chat_id
=
purple_conv_chat_get_id
(
chat
);
ning_chat_whisper
(
pc
,
chat_id
,
who
,
message
);
return
1
;
}
}
return
-1
;
}
int
ning_chat_send
(
PurpleConnection
*
pc
,
int
id
,
const
char
*
message
,
PurpleMessageFlags
flags
)
{
if
(
flags
!=
PURPLE_MESSAGE_SEND
)
return
-1
;
ning_chat_whisper
(
pc
,
id
,
NULL
,
message
);
return
1
;
}
void
ning_join_chat_by_name
(
NingAccount
*
na
,
const
gchar
*
roomId
)
{
NingChat
*
chat
;
if
(
na
==
NULL
||
roomId
==
NULL
)
return
;
chat
=
g_new0
(
NingChat
,
1
);
chat
->
na
=
na
;
chat
->
roomId
=
g_strdup
(
roomId
);
chat
->
purple_id
=
g_str_hash
(
roomId
);
chat
->
ning_hash
=
g_strdup
(
"null"
);
serv_got_joined_chat
(
na
->
pc
,
g_str_hash
(
roomId
),
roomId
);
//get history
ning_chat_get_history
(
chat
);
//get user list
ning_chat_get_users
(
chat
);
chat
->
userlist_timer
=
purple_timeout_add_seconds
(
60
,
(
GSourceFunc
)
ning_chat_get_users
,
chat
);
//start message poll
ning_chat_poll_messages
(
chat
);
chat
->
message_poll_timer
=
purple_timeout_add_seconds
(
180
,
(
GSourceFunc
)
ning_chat_poll_messages
,
chat
);
na
->
chats
=
g_list_append
(
na
->
chats
,
chat
);
}
void
ning_join_chat
(
PurpleConnection
*
pc
,
GHashTable
*
components
)
{
NingAccount
*
na
;
if
(
pc
==
NULL
||
pc
->
proto_data
==
NULL
||
components
==
NULL
)
return
;
na
=
pc
->
proto_data
;
ning_join_chat_by_name
(
na
,
g_hash_table_lookup
(
components
,
"name"
));
}