pidgin/purple-plugin-pack
Clone
Summary
Browse
Changes
Graph
Add a .reviewboardrc file
2020-07-14, Gary Kramlich
ea3780da6a08
Add a .reviewboardrc file
Testing Done:
Created this review request using it :)
Reviewed at https://reviews.imfreedom.org/r/29/
/*
* 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"
));
}