pidgin/pidgin
Clone
Summary
Browse
Changes
Graph
rename gtkmenutray.[ch] to pidginmenutray.[ch]
2019-11-18, Gary Kramlich
352d23243db5
rename gtkmenutray.[ch] to pidginmenutray.[ch]
/* purple
*
* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* Rewritten from scratch during Google Summer of Code 2012
* by Tomek Wasilczyk (http://www.wasilczyk.pl).
*
* Previously implemented by:
* - Arkadiusz Miskiewicz <misiek@pld.org.pl> - first implementation (2001);
* - Bartosz Oler <bartosz@bzimage.us> - reimplemented during GSoC 2005;
* - Krzysztof Klinikowski <grommasher@gmail.com> - some parts (2009-2011).
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include
"pubdir-prpl.h"
#include
"gg.h"
#include
<debug.h>
#include
<request.h>
#include
"oauth/oauth-purple.h"
#include
"xml.h"
#include
"utils.h"
#include
"status.h"
typedef
struct
{
PurpleConnection
*
gc
;
ggp_pubdir_request_cb
cb
;
void
*
user_data
;
enum
{
GGP_PUBDIR_REQUEST_TYPE_INFO
,
GGP_PUBDIR_REQUEST_TYPE_SEARCH
,
}
type
;
union
{
struct
{
uin_t
uin
;
}
user_info
;
ggp_pubdir_search_form
*
search_form
;
}
params
;
}
ggp_pubdir_request
;
/* Searching for buddies. */
#define GGP_PUBDIR_SEARCH_TITLE _("Gadu-Gadu Public Directory")
#define GGP_PUBDIR_SEARCH_PER_PAGE 20
struct
_ggp_pubdir_search_form
{
gchar
*
nick
,
*
city
;
ggp_pubdir_gender
gender
;
int
offset
;
int
limit
;
void
*
display_handle
;
};
/* For ggp_pubdir_search_results_next, which is called by this. */
static
void
ggp_pubdir_search_results_display
(
PurpleConnection
*
gc
,
int
records_count
,
const
ggp_pubdir_record
*
records
,
int
next_offset
,
void
*
user_data
);
/******************************************************************************/
static
const
gchar
*
ggp_pubdir_provinces
[]
=
{
N_
(
"Not specified"
),
"dolnośląskie"
,
"kujawsko-pomorskie"
,
"lubelskie"
,
"lubuskie"
,
"łódzkie"
,
"małopolskie"
,
"mazowieckie"
,
"opolskie"
,
"podkarpackie"
,
"podlaskie"
,
"pomorskie"
,
"śląskie"
,
"świętokrzyskie"
,
"warmińsko-mazurskie"
,
"wielkopolskie"
,
"zachodniopomorskie"
,
};
static
gsize
ggp_pubdir_provinces_count
=
sizeof
(
ggp_pubdir_provinces
)
/
sizeof
(
gchar
*
);
/******************************************************************************/
static
void
ggp_pubdir_record_free
(
ggp_pubdir_record
*
records
,
int
count
)
{
int
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
g_free
(
records
[
i
].
label
);
g_free
(
records
[
i
].
nickname
);
g_free
(
records
[
i
].
first_name
);
g_free
(
records
[
i
].
last_name
);
g_free
(
records
[
i
].
city
);
}
g_free
(
records
);
}
static
void
ggp_pubdir_search_form_free
(
ggp_pubdir_search_form
*
form
)
{
g_free
(
form
->
nick
);
g_free
(
form
->
city
);
g_free
(
form
);
}
static
void
ggp_pubdir_request_free
(
ggp_pubdir_request
*
request
)
{
if
(
request
->
type
==
GGP_PUBDIR_REQUEST_TYPE_SEARCH
)
ggp_pubdir_search_form_free
(
request
->
params
.
search_form
);
g_free
(
request
);
}
static
void
ggp_pubdir_got_data
(
G_GNUC_UNUSED
SoupSession
*
session
,
SoupMessage
*
msg
,
gpointer
_request
)
{
ggp_pubdir_request
*
request
=
_request
;
PurpleConnection
*
gc
=
request
->
gc
;
gboolean
succ
=
TRUE
;
PurpleXmlNode
*
xml
;
const
gchar
*
xml_raw
;
unsigned
int
status
,
next_offset
;
int
record_count
,
i
;
ggp_pubdir_record
*
records
;
xml_raw
=
msg
->
response_body
->
data
;
if
(
purple_debug_is_verbose
()
&&
purple_debug_is_unsafe
())
{
purple_debug_misc
(
"gg"
,
"ggp_pubdir_got_data: xml=[%s]
\n
"
,
xml_raw
);
}
xml
=
purple_xmlnode_from_str
(
xml_raw
,
-1
);
if
(
xml
==
NULL
)
{
purple_debug_error
(
"gg"
,
"ggp_pubdir_got_data: "
"invalid xml
\n
"
);
request
->
cb
(
gc
,
-1
,
NULL
,
0
,
request
->
user_data
);
ggp_pubdir_request_free
(
request
);
return
;
}
succ
&=
ggp_xml_get_uint
(
xml
,
"status"
,
&
status
);
if
(
!
ggp_xml_get_uint
(
xml
,
"nextOffset"
,
&
next_offset
))
next_offset
=
0
;
xml
=
purple_xmlnode_get_child
(
xml
,
"users"
);
if
(
!
succ
||
status
!=
0
||
!
xml
)
{
purple_debug_error
(
"gg"
,
"ggp_pubdir_got_data: "
"invalid reply
\n
"
);
request
->
cb
(
gc
,
-1
,
NULL
,
0
,
request
->
user_data
);
ggp_pubdir_request_free
(
request
);
return
;
}
record_count
=
ggp_xml_child_count
(
xml
,
"user"
);
records
=
g_new0
(
ggp_pubdir_record
,
record_count
);
xml
=
purple_xmlnode_get_child
(
xml
,
"user"
);
i
=
0
;
while
(
xml
)
{
ggp_pubdir_record
*
record
=
&
records
[
i
++
];
gchar
*
city
=
NULL
,
*
birth_s
=
NULL
;
unsigned
int
gender
=
0
;
const
gchar
*
uin_s
;
g_assert
(
i
<=
record_count
);
record
->
uin
=
ggp_str_to_uin
(
purple_xmlnode_get_attrib
(
xml
,
"uin"
));
if
(
record
->
uin
==
0
)
ggp_xml_get_uint
(
xml
,
"uin"
,
&
record
->
uin
);
if
(
record
->
uin
==
0
)
purple_debug_error
(
"gg"
,
"ggp_pubdir_got_data:"
" invalid uin
\n
"
);
uin_s
=
ggp_uin_to_str
(
record
->
uin
);
ggp_xml_get_string
(
xml
,
"label"
,
&
record
->
label
);
ggp_xml_get_string
(
xml
,
"nick"
,
&
record
->
nickname
);
ggp_xml_get_string
(
xml
,
"name"
,
&
record
->
first_name
);
ggp_xml_get_string
(
xml
,
"surname"
,
&
record
->
last_name
);
ggp_xml_get_string
(
xml
,
"city"
,
&
city
);
ggp_xml_get_string
(
xml
,
"birth"
,
&
birth_s
);
ggp_xml_get_uint
(
xml
,
"gender"
,
&
gender
);
ggp_xml_get_uint
(
xml
,
"age"
,
&
record
->
age
);
ggp_xml_get_uint
(
xml
,
"province"
,
&
record
->
province
);
record
->
label
=
ggp_free_if_equal
(
record
->
label
,
uin_s
);
record
->
label
=
ggp_free_if_equal
(
record
->
label
,
""
);
record
->
nickname
=
ggp_free_if_equal
(
record
->
nickname
,
uin_s
);
record
->
nickname
=
ggp_free_if_equal
(
record
->
nickname
,
""
);
record
->
first_name
=
ggp_free_if_equal
(
record
->
first_name
,
""
);
record
->
last_name
=
ggp_free_if_equal
(
record
->
last_name
,
""
);
if
(
record
->
label
)
{}
else
if
(
record
->
nickname
)
record
->
label
=
g_strdup
(
record
->
nickname
);
else
if
(
record
->
first_name
&&
record
->
last_name
)
record
->
label
=
g_strdup_printf
(
"%s %s"
,
record
->
first_name
,
record
->
last_name
);
else
if
(
record
->
first_name
)
record
->
label
=
g_strdup
(
record
->
first_name
);
else
if
(
record
->
last_name
)
record
->
label
=
g_strdup
(
record
->
last_name
);
if
(
record
->
label
)
g_strstrip
(
record
->
label
);
if
(
record
->
nickname
)
g_strstrip
(
record
->
nickname
);
if
(
gender
==
1
)
record
->
gender
=
GGP_PUBDIR_GENDER_FEMALE
;
else
if
(
gender
==
2
)
record
->
gender
=
GGP_PUBDIR_GENDER_MALE
;
else
record
->
gender
=
GGP_PUBDIR_GENDER_UNSPECIFIED
;
if
(
city
&&
city
[
0
]
!=
'\0'
)
record
->
city
=
g_strdup
(
city
);
if
(
record
->
city
)
g_strstrip
(
record
->
city
);
if
(
!
record
->
city
)
{
g_free
(
record
->
city
);
record
->
city
=
NULL
;
}
record
->
birth
=
ggp_date_from_iso8601
(
birth_s
);
/*TODO: calculate age from birth */
if
(
purple_debug_is_verbose
())
{
purple_debug_misc
(
"gg"
,
"ggp_pubdir_got_data: [uin:%d] "
"[label:%s] [nick:%s] [first name:%s] "
"[last name:%s] [city:%s] [gender:%d] [age:%d] "
"[birth:%lu]
\n
"
,
record
->
uin
,
record
->
label
,
record
->
nickname
,
record
->
first_name
,
record
->
last_name
,
record
->
city
,
record
->
gender
,
record
->
age
,
record
->
birth
);
}
g_free
(
city
);
xml
=
purple_xmlnode_get_next_twin
(
xml
);
}
request
->
cb
(
gc
,
record_count
,
records
,
next_offset
,
request
->
user_data
);
ggp_pubdir_request_free
(
request
);
ggp_pubdir_record_free
(
records
,
record_count
);
}
static
void
ggp_pubdir_get_info_got_token
(
PurpleConnection
*
gc
,
const
gchar
*
token
,
gpointer
_request
)
{
GGPInfo
*
info
=
NULL
;
gchar
*
url
;
SoupMessage
*
msg
;
ggp_pubdir_request
*
request
=
_request
;
PURPLE_ASSERT_CONNECTION_IS_VALID
(
gc
);
if
(
!
token
)
{
request
->
cb
(
gc
,
-1
,
NULL
,
0
,
request
->
user_data
);
ggp_pubdir_request_free
(
request
);
return
;
}
info
=
purple_connection_get_protocol_data
(
gc
);
url
=
g_strdup_printf
(
"http://api.gadu-gadu.pl/users/%u"
,
request
->
params
.
user_info
.
uin
);
msg
=
soup_message_new
(
"GET"
,
url
);
g_free
(
url
);
soup_message_headers_replace
(
msg
->
request_headers
,
"Authorization"
,
token
);
soup_session_queue_message
(
info
->
http
,
msg
,
ggp_pubdir_got_data
,
request
);
}
void
ggp_pubdir_get_info
(
PurpleConnection
*
gc
,
uin_t
uin
,
ggp_pubdir_request_cb
cb
,
void
*
user_data
)
{
ggp_pubdir_request
*
request
=
g_new0
(
ggp_pubdir_request
,
1
);
gchar
*
url
;
request
->
type
=
GGP_PUBDIR_REQUEST_TYPE_INFO
;
request
->
gc
=
gc
;
request
->
cb
=
cb
;
request
->
user_data
=
user_data
;
request
->
params
.
user_info
.
uin
=
uin
;
url
=
g_strdup_printf
(
"http://api.gadu-gadu.pl/users/%u"
,
uin
);
ggp_oauth_request
(
gc
,
ggp_pubdir_get_info_got_token
,
request
,
"GET"
,
url
);
g_free
(
url
);
}
static
void
ggp_pubdir_get_info_protocol_got
(
PurpleConnection
*
gc
,
int
records_count
,
const
ggp_pubdir_record
*
records
,
int
next_offset
,
void
*
_uin_p
)
{
uin_t
uin
=
*
((
uin_t
*
)
_uin_p
);
PurpleNotifyUserInfo
*
info
=
purple_notify_user_info_new
();
const
ggp_pubdir_record
*
record
=
&
records
[
0
];
PurpleBuddy
*
buddy
;
g_free
(
_uin_p
);
if
(
records_count
<
1
)
{
purple_debug_error
(
"gg"
,
"ggp_pubdir_get_info_protocol_got: "
"couldn't get info for %u
\n
"
,
uin
);
purple_notify_user_info_add_pair_plaintext
(
info
,
NULL
,
_
(
"Cannot get user information"
));
purple_notify_userinfo
(
gc
,
ggp_uin_to_str
(
uin
),
info
,
NULL
,
NULL
);
purple_notify_user_info_destroy
(
info
);
return
;
}
purple_debug_info
(
"gg"
,
"ggp_pubdir_get_info_protocol_got: %u
\n
"
,
uin
);
g_assert
(
uin
==
record
->
uin
);
g_assert
(
records_count
==
1
);
buddy
=
purple_blist_find_buddy
(
purple_connection_get_account
(
gc
),
ggp_uin_to_str
(
uin
));
if
(
buddy
)
{
const
char
*
alias
;
PurpleStatus
*
status
;
gchar
*
status_message
;
alias
=
purple_buddy_get_alias_only
(
buddy
);
if
(
alias
)
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Alias"
),
alias
);
status
=
purple_presence_get_active_status
(
purple_buddy_get_presence
(
buddy
));
ggp_status_from_purplestatus
(
status
,
&
status_message
);
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Status"
),
purple_status_get_name
(
status
));
if
(
status_message
)
{
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Message"
),
status_message
);
}
}
if
(
record
->
nickname
)
{
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Nickname"
),
record
->
nickname
);
}
if
(
record
->
first_name
)
{
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"First name"
),
record
->
first_name
);
}
if
(
record
->
last_name
)
{
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Last name"
),
record
->
last_name
);
}
if
(
record
->
gender
!=
GGP_PUBDIR_GENDER_UNSPECIFIED
)
{
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Gender"
),
record
->
gender
==
GGP_PUBDIR_GENDER_FEMALE
?
_
(
"Female"
)
:
_
(
"Male"
));
}
if
(
record
->
city
)
{
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"City"
),
record
->
city
);
}
if
(
record
->
birth
)
{
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Birthday"
),
ggp_date_strftime
(
"%Y-%m-%d"
,
record
->
birth
));
}
else
if
(
record
->
age
)
{
gchar
*
age_s
=
g_strdup_printf
(
"%d"
,
record
->
age
);
purple_notify_user_info_add_pair_plaintext
(
info
,
_
(
"Age"
),
age_s
);
g_free
(
age_s
);
}
purple_notify_userinfo
(
gc
,
ggp_uin_to_str
(
uin
),
info
,
NULL
,
NULL
);
purple_notify_user_info_destroy
(
info
);
}
void
ggp_pubdir_get_info_protocol
(
PurpleConnection
*
gc
,
const
char
*
name
)
{
uin_t
uin
=
ggp_str_to_uin
(
name
);
uin_t
*
uin_p
=
g_new0
(
uin_t
,
1
);
*
uin_p
=
uin
;
purple_debug_info
(
"gg"
,
"ggp_pubdir_get_info_protocol: %u"
,
uin
);
ggp_pubdir_get_info
(
gc
,
uin
,
ggp_pubdir_get_info_protocol_got
,
uin_p
);
}
static
void
ggp_pubdir_request_buddy_alias_got
(
PurpleConnection
*
gc
,
int
records_count
,
const
ggp_pubdir_record
*
records
,
int
next_offset
,
void
*
user_data
)
{
uin_t
uin
;
const
gchar
*
alias
;
if
(
records_count
<
0
)
{
purple_debug_error
(
"gg"
,
"ggp_pubdir_request_buddy_alias_got: "
"couldn't get info for user
\n
"
);
return
;
}
uin
=
records
[
0
].
uin
;
alias
=
records
[
0
].
label
;
if
(
!
alias
)
{
purple_debug_info
(
"gg"
,
"ggp_pubdir_request_buddy_alias_got: "
"public alias for %u is not available
\n
"
,
uin
);
return
;
}
purple_debug_info
(
"gg"
,
"ggp_pubdir_request_buddy_alias_got: "
"public alias for %u is
\"
%s
\"\n
"
,
uin
,
alias
);
purple_serv_got_alias
(
gc
,
ggp_uin_to_str
(
uin
),
alias
);
}
void
ggp_pubdir_request_buddy_alias
(
PurpleConnection
*
gc
,
PurpleBuddy
*
buddy
)
{
uin_t
uin
=
ggp_str_to_uin
(
purple_buddy_get_name
(
buddy
));
purple_debug_info
(
"gg"
,
"ggp_pubdir_request_buddy_alias: %u"
,
uin
);
ggp_pubdir_get_info
(
gc
,
uin
,
ggp_pubdir_request_buddy_alias_got
,
NULL
);
}
/*******************************************************************************
* Searching for buddies.
******************************************************************************/
static
ggp_pubdir_search_form
*
ggp_pubdir_search_form_clone
(
const
ggp_pubdir_search_form
*
form
)
{
ggp_pubdir_search_form
*
dup
=
g_new
(
ggp_pubdir_search_form
,
1
);
dup
->
nick
=
g_strdup
(
form
->
nick
);
dup
->
city
=
g_strdup
(
form
->
city
);
dup
->
gender
=
form
->
gender
;
dup
->
offset
=
form
->
offset
;
dup
->
limit
=
form
->
limit
;
dup
->
display_handle
=
form
->
display_handle
;
return
dup
;
}
static
gchar
*
ggp_pubdir_search_make_query
(
const
ggp_pubdir_search_form
*
form
)
{
gchar
*
nick
,
*
city
,
*
gender
;
gchar
*
query
;
if
(
form
->
nick
&&
form
->
nick
[
0
]
!=
'\0'
)
{
gchar
*
nick_e
=
g_uri_escape_string
(
form
->
nick
,
NULL
,
FALSE
);
nick
=
g_strdup_printf
(
"&nick=%s"
,
nick_e
);
g_free
(
nick_e
);
}
else
nick
=
g_strdup
(
""
);
if
(
form
->
city
&&
form
->
city
[
0
]
!=
'\0'
)
{
gchar
*
city_e
=
g_uri_escape_string
(
form
->
city
,
NULL
,
FALSE
);
city
=
g_strdup_printf
(
"&city=%s"
,
city_e
);
g_free
(
city_e
);
}
else
city
=
g_strdup
(
""
);
if
(
form
->
gender
!=
GGP_PUBDIR_GENDER_UNSPECIFIED
)
{
gender
=
g_strdup_printf
(
"&gender=%d"
,
form
->
gender
==
GGP_PUBDIR_GENDER_MALE
?
2
:
1
);
}
else
gender
=
g_strdup
(
""
);
query
=
g_strdup_printf
(
"/users.xml?offset=%d&limit=%d%s%s%s"
,
form
->
offset
,
form
->
limit
,
nick
,
city
,
gender
);
g_free
(
nick
);
g_free
(
city
);
g_free
(
gender
);
return
query
;
}
static
void
ggp_pubdir_search_got_token
(
PurpleConnection
*
gc
,
const
gchar
*
token
,
gpointer
_request
)
{
GGPInfo
*
info
=
NULL
;
gchar
*
url
;
SoupMessage
*
msg
;
ggp_pubdir_request
*
request
=
_request
;
gchar
*
query
;
PURPLE_ASSERT_CONNECTION_IS_VALID
(
gc
);
if
(
!
token
)
{
request
->
cb
(
gc
,
-1
,
NULL
,
0
,
request
->
user_data
);
ggp_pubdir_request_free
(
request
);
return
;
}
purple_debug_misc
(
"gg"
,
"ggp_pubdir_search_got_token
\n
"
);
query
=
ggp_pubdir_search_make_query
(
request
->
params
.
search_form
);
info
=
purple_connection_get_protocol_data
(
gc
);
url
=
g_strdup_printf
(
"http://api.gadu-gadu.pl%s"
,
query
);
msg
=
soup_message_new
(
"GET"
,
url
);
soup_message_headers_replace
(
msg
->
request_headers
,
"Authorization"
,
token
);
soup_session_queue_message
(
info
->
http
,
msg
,
ggp_pubdir_got_data
,
request
);
g_free
(
url
);
g_free
(
query
);
}
static
void
ggp_pubdir_search_execute
(
PurpleConnection
*
gc
,
const
ggp_pubdir_search_form
*
form
,
ggp_pubdir_request_cb
cb
,
void
*
user_data
)
{
ggp_pubdir_request
*
request
=
g_new0
(
ggp_pubdir_request
,
1
);
gchar
*
url
;
ggp_pubdir_search_form
*
local_form
=
ggp_pubdir_search_form_clone
(
form
);
gchar
*
query
;
request
->
type
=
GGP_PUBDIR_REQUEST_TYPE_SEARCH
;
request
->
gc
=
gc
;
request
->
cb
=
cb
;
request
->
user_data
=
user_data
;
request
->
params
.
search_form
=
local_form
;
query
=
ggp_pubdir_search_make_query
(
form
);
purple_debug_misc
(
"gg"
,
"ggp_pubdir_search_execute: %s"
,
query
);
url
=
g_strdup_printf
(
"http://api.gadu-gadu.pl%s"
,
query
);
ggp_oauth_request
(
gc
,
ggp_pubdir_search_got_token
,
request
,
"GET"
,
url
);
g_free
(
query
);
g_free
(
url
);
}
static
void
ggp_pubdir_search_results_new
(
PurpleConnection
*
gc
,
GList
*
row
,
gpointer
_form
)
{
ggp_pubdir_search_form
*
form
=
_form
;
ggp_pubdir_search
(
gc
,
form
);
}
static
void
ggp_pubdir_search_results_close
(
gpointer
_form
)
{
ggp_pubdir_search_form
*
form
=
_form
;
ggp_pubdir_search_form_free
(
form
);
}
static
void
ggp_pubdir_search_results_next
(
PurpleConnection
*
gc
,
GList
*
row
,
gpointer
_form
)
{
ggp_pubdir_search_form
*
form
=
_form
;
ggp_pubdir_search_execute
(
gc
,
form
,
ggp_pubdir_search_results_display
,
form
);
}
static
void
ggp_pubdir_search_results_add
(
PurpleConnection
*
gc
,
GList
*
row
,
gpointer
_form
)
{
purple_blist_request_add_buddy
(
purple_connection_get_account
(
gc
),
g_list_nth_data
(
row
,
0
),
NULL
,
g_list_nth_data
(
row
,
1
));
}
static
void
ggp_pubdir_search_results_im
(
PurpleConnection
*
gc
,
GList
*
row
,
gpointer
_form
)
{
purple_conversation_present
(
PURPLE_CONVERSATION
(
purple_im_conversation_new
(
purple_connection_get_account
(
gc
),
g_list_nth_data
(
row
,
0
))));
}
static
void
ggp_pubdir_search_results_info
(
PurpleConnection
*
gc
,
GList
*
row
,
gpointer
_form
)
{
ggp_pubdir_get_info_protocol
(
gc
,
g_list_nth_data
(
row
,
0
));
}
static
void
ggp_pubdir_search_results_display
(
PurpleConnection
*
gc
,
int
records_count
,
const
ggp_pubdir_record
*
records
,
int
next_offset
,
void
*
_form
)
{
ggp_pubdir_search_form
*
form
=
_form
;
PurpleNotifySearchResults
*
results
;
int
i
;
purple_debug_info
(
"gg"
,
"ggp_pubdir_search_results_display: "
"got %d records (next offset: %d)
\n
"
,
records_count
,
next_offset
);
if
(
records_count
<
0
||
(
records_count
==
0
&&
form
->
offset
!=
0
))
{
purple_notify_error
(
gc
,
GGP_PUBDIR_SEARCH_TITLE
,
_
(
"Error while searching for buddies"
),
NULL
,
purple_request_cpar_from_connection
(
gc
));
ggp_pubdir_search_form_free
(
form
);
return
;
}
if
(
records_count
==
0
)
{
purple_notify_info
(
gc
,
GGP_PUBDIR_SEARCH_TITLE
,
_
(
"No matching users found"
),
_
(
"There are no users matching your search criteria."
),
purple_request_cpar_from_connection
(
gc
));
ggp_pubdir_search_form_free
(
form
);
return
;
}
form
->
offset
=
next_offset
;
results
=
purple_notify_searchresults_new
();
purple_notify_searchresults_column_add
(
results
,
purple_notify_searchresults_column_new
(
_
(
"GG Number"
)));
purple_notify_searchresults_column_add
(
results
,
purple_notify_searchresults_column_new
(
_
(
"Name"
)));
purple_notify_searchresults_column_add
(
results
,
purple_notify_searchresults_column_new
(
_
(
"City"
)));
purple_notify_searchresults_column_add
(
results
,
purple_notify_searchresults_column_new
(
_
(
"Gender"
)));
purple_notify_searchresults_column_add
(
results
,
purple_notify_searchresults_column_new
(
_
(
"Age"
)));
for
(
i
=
0
;
i
<
records_count
;
i
++
)
{
GList
*
row
=
NULL
;
const
ggp_pubdir_record
*
record
=
&
records
[
i
];
gchar
*
gender
=
NULL
,
*
age
=
NULL
;
if
(
record
->
gender
==
GGP_PUBDIR_GENDER_MALE
)
gender
=
g_strdup
(
"male"
);
else
if
(
record
->
gender
==
GGP_PUBDIR_GENDER_FEMALE
)
gender
=
g_strdup
(
"female"
);
if
(
record
->
age
)
age
=
g_strdup_printf
(
"%d"
,
record
->
age
);
row
=
g_list_append
(
row
,
g_strdup
(
ggp_uin_to_str
(
record
->
uin
)));
row
=
g_list_append
(
row
,
g_strdup
(
record
->
label
));
row
=
g_list_append
(
row
,
g_strdup
(
record
->
city
));
row
=
g_list_append
(
row
,
gender
);
row
=
g_list_append
(
row
,
age
);
purple_notify_searchresults_row_add
(
results
,
row
);
}
purple_notify_searchresults_button_add
(
results
,
PURPLE_NOTIFY_BUTTON_ADD
,
ggp_pubdir_search_results_add
);
purple_notify_searchresults_button_add
(
results
,
PURPLE_NOTIFY_BUTTON_IM
,
ggp_pubdir_search_results_im
);
purple_notify_searchresults_button_add
(
results
,
PURPLE_NOTIFY_BUTTON_INFO
,
ggp_pubdir_search_results_info
);
purple_notify_searchresults_button_add_labeled
(
results
,
_
(
"New search"
),
ggp_pubdir_search_results_new
);
if
(
next_offset
!=
0
)
purple_notify_searchresults_button_add
(
results
,
PURPLE_NOTIFY_BUTTON_CONTINUE
,
ggp_pubdir_search_results_next
);
if
(
!
form
->
display_handle
)
form
->
display_handle
=
purple_notify_searchresults
(
gc
,
GGP_PUBDIR_SEARCH_TITLE
,
_
(
"Search results"
),
NULL
,
results
,
ggp_pubdir_search_results_close
,
form
);
else
purple_notify_searchresults_new_rows
(
gc
,
results
,
form
->
display_handle
);
g_assert
(
form
->
display_handle
);
}
static
void
ggp_pubdir_search_request
(
PurpleConnection
*
gc
,
PurpleRequestFields
*
fields
)
{
ggp_pubdir_search_form
*
form
=
g_new0
(
ggp_pubdir_search_form
,
1
);
purple_debug_info
(
"gg"
,
"ggp_pubdir_search_request"
);
form
->
nick
=
g_strdup
(
purple_request_fields_get_string
(
fields
,
"name"
));
form
->
city
=
g_strdup
(
purple_request_fields_get_string
(
fields
,
"city"
));
form
->
gender
=
GPOINTER_TO_INT
(
purple_request_fields_get_choice
(
fields
,
"gender"
));
form
->
offset
=
0
;
form
->
limit
=
GGP_PUBDIR_SEARCH_PER_PAGE
;
ggp_pubdir_search_execute
(
gc
,
form
,
ggp_pubdir_search_results_display
,
form
);
}
void
ggp_pubdir_search
(
PurpleConnection
*
gc
,
const
ggp_pubdir_search_form
*
form
)
{
PurpleRequestFields
*
fields
;
PurpleRequestFieldGroup
*
group
;
PurpleRequestField
*
field
;
purple_debug_info
(
"gg"
,
"ggp_pubdir_search"
);
fields
=
purple_request_fields_new
();
group
=
purple_request_field_group_new
(
NULL
);
purple_request_fields_add_group
(
fields
,
group
);
field
=
purple_request_field_string_new
(
"name"
,
_
(
"Name"
),
form
?
form
->
nick
:
NULL
,
FALSE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_string_new
(
"city"
,
_
(
"City"
),
form
?
form
->
city
:
NULL
,
FALSE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_choice_new
(
"gender"
,
_
(
"Gender"
),
form
?
GINT_TO_POINTER
(
form
->
gender
)
:
NULL
);
purple_request_field_choice_add
(
field
,
_
(
"Male or female"
),
NULL
);
purple_request_field_choice_add
(
field
,
_
(
"Male"
),
GINT_TO_POINTER
(
GGP_PUBDIR_GENDER_MALE
));
purple_request_field_choice_add
(
field
,
_
(
"Female"
),
GINT_TO_POINTER
(
GGP_PUBDIR_GENDER_FEMALE
));
purple_request_field_group_add_field
(
group
,
field
);
purple_request_fields
(
gc
,
_
(
"Find buddies"
),
_
(
"Find buddies"
),
_
(
"Please, enter your search criteria below"
),
fields
,
_
(
"OK"
),
G_CALLBACK
(
ggp_pubdir_search_request
),
_
(
"Cancel"
),
NULL
,
purple_request_cpar_from_connection
(
gc
),
gc
);
}
/*******************************************************************************
* Own profile.
******************************************************************************/
static
void
ggp_pubdir_set_info_got_response
(
G_GNUC_UNUSED
SoupSession
*
session
,
SoupMessage
*
msg
,
gpointer
user_data
)
{
if
(
!
SOUP_STATUS_IS_SUCCESSFUL
(
msg
->
status_code
))
{
purple_debug_error
(
"gg"
,
"ggp_pubdir_set_info_got_response: failed"
);
return
;
}
purple_debug_info
(
"gg"
,
"ggp_pubdir_set_info_got_response: [%s]"
,
msg
->
response_body
->
data
);
/* <result><status>0</status></result> */
/* TODO: notify about failure */
}
static
void
ggp_pubdir_set_info_got_token
(
PurpleConnection
*
gc
,
const
gchar
*
token
,
gpointer
_record
)
{
ggp_pubdir_record
*
record
=
_record
;
GGPInfo
*
info
=
NULL
;
SoupMessage
*
msg
;
gchar
*
url
;
gchar
*
request_data
;
gchar
*
name
,
*
surname
,
*
city
;
uin_t
uin
=
record
->
uin
;
PURPLE_ASSERT_CONNECTION_IS_VALID
(
gc
);
if
(
!
token
)
{
/* TODO: notify about failure */
ggp_pubdir_record_free
(
record
,
1
);
return
;
}
info
=
purple_connection_get_protocol_data
(
gc
);
name
=
g_uri_escape_string
(
record
->
first_name
,
NULL
,
FALSE
);
surname
=
g_uri_escape_string
(
record
->
last_name
,
NULL
,
FALSE
);
city
=
g_uri_escape_string
(
record
->
city
,
NULL
,
FALSE
);
request_data
=
g_strdup_printf
(
"name=%s&"
"surname=%s&"
"birth=%sT10:00:00%%2B00:00&"
"birth_priv=2&"
"gender=%d&"
"gender_priv=2&"
"city=%s&"
"province=%d"
,
name
,
surname
,
ggp_date_strftime
(
"%Y-%m-%d"
,
record
->
birth
),
record
->
gender
,
city
,
record
->
province
);
if
(
purple_debug_is_verbose
()
&&
purple_debug_is_unsafe
())
{
purple_debug_misc
(
"gg"
,
"ggp_pubdir_set_info_got_token: "
"query [%s]
\n
"
,
request_data
);
}
url
=
g_strdup_printf
(
"http://api.gadu-gadu.pl/users/%u.xml"
,
uin
);
msg
=
soup_message_new
(
"PUT"
,
url
);
soup_message_headers_replace
(
msg
->
request_headers
,
"Authorization"
,
token
);
soup_message_set_request
(
msg
,
"application/x-www-form-urlencoded"
,
SOUP_MEMORY_TAKE
,
request_data
,
-1
);
soup_session_queue_message
(
info
->
http
,
msg
,
ggp_pubdir_set_info_got_response
,
NULL
);
g_free
(
url
);
ggp_pubdir_record_free
(
record
,
1
);
}
static
void
ggp_pubdir_set_info_request
(
PurpleConnection
*
gc
,
PurpleRequestFields
*
fields
)
{
gchar
*
url
;
uin_t
uin
=
ggp_str_to_uin
(
purple_account_get_username
(
purple_connection_get_account
(
gc
)));
ggp_pubdir_record
*
record
=
g_new0
(
ggp_pubdir_record
,
1
);
gchar
*
birth_s
;
purple_debug_info
(
"gg"
,
"ggp_pubdir_set_info_request"
);
record
->
uin
=
uin
;
record
->
first_name
=
g_strdup
(
purple_request_fields_get_string
(
fields
,
"first_name"
));
record
->
last_name
=
g_strdup
(
purple_request_fields_get_string
(
fields
,
"last_name"
));
record
->
gender
=
GPOINTER_TO_INT
(
purple_request_fields_get_choice
(
fields
,
"gender"
));
record
->
city
=
g_strdup
(
purple_request_fields_get_string
(
fields
,
"city"
));
record
->
province
=
GPOINTER_TO_INT
(
purple_request_fields_get_choice
(
fields
,
"province"
));
birth_s
=
g_strdup_printf
(
"%sT10:00:00+00:00"
,
purple_request_fields_get_string
(
fields
,
"birth_date"
));
record
->
birth
=
ggp_date_from_iso8601
(
birth_s
);
g_free
(
birth_s
);
purple_debug_info
(
"gg"
,
"ggp_pubdir_set_info_request: birth [%lu][%s]"
,
record
->
birth
,
purple_request_fields_get_string
(
fields
,
"birth_date"
));
url
=
g_strdup_printf
(
"http://api.gadu-gadu.pl/users/%u.xml"
,
uin
);
ggp_oauth_request
(
gc
,
ggp_pubdir_set_info_got_token
,
record
,
"PUT"
,
url
);
g_free
(
url
);
}
static
void
ggp_pubdir_set_info_dialog
(
PurpleConnection
*
gc
,
int
records_count
,
const
ggp_pubdir_record
*
records
,
int
next_offset
,
void
*
user_data
)
{
PurpleRequestFields
*
fields
;
PurpleRequestFieldGroup
*
group
;
PurpleRequestField
*
field
;
gsize
i
;
const
ggp_pubdir_record
*
record
;
purple_debug_info
(
"gg"
,
"ggp_pubdir_set_info_dialog (record: %d)"
,
records_count
);
record
=
(
records_count
==
1
?
&
records
[
0
]
:
NULL
);
fields
=
purple_request_fields_new
();
group
=
purple_request_field_group_new
(
NULL
);
purple_request_fields_add_group
(
fields
,
group
);
field
=
purple_request_field_string_new
(
"first_name"
,
_
(
"First name"
),
record
?
record
->
first_name
:
NULL
,
FALSE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_string_new
(
"last_name"
,
_
(
"Last name"
),
record
?
record
->
last_name
:
NULL
,
FALSE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_choice_new
(
"gender"
,
_
(
"Gender"
),
record
?
GINT_TO_POINTER
(
record
->
gender
)
:
GGP_PUBDIR_GENDER_UNSPECIFIED
);
purple_request_field_set_required
(
field
,
TRUE
);
purple_request_field_choice_add
(
field
,
_
(
"Male"
),
GINT_TO_POINTER
(
GGP_PUBDIR_GENDER_MALE
));
purple_request_field_choice_add
(
field
,
_
(
"Female"
),
GINT_TO_POINTER
(
GGP_PUBDIR_GENDER_FEMALE
));
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_string_new
(
"birth_date"
,
_
(
"Birth Day"
),
(
record
&&
record
->
birth
)
?
ggp_date_strftime
(
"%Y-%m-%d"
,
record
->
birth
)
:
NULL
,
FALSE
);
purple_request_field_set_required
(
field
,
TRUE
);
purple_request_field_group_add_field
(
group
,
field
);
field
=
purple_request_field_string_new
(
"city"
,
_
(
"City"
),
record
?
record
->
city
:
NULL
,
FALSE
);
purple_request_field_group_add_field
(
group
,
field
);
/* Translators: This word is basically used to describe a Polish
province. Gadu-Gadu users outside of Poland might choose to enter some
equivalent value for themselves. For example, users in the USA might
use their state (e.g. New York). If there is an equivalent term for
your language, feel free to use it. Otherwise it's probably acceptable
to leave it changed or transliterate it into your alphabet. */
field
=
purple_request_field_choice_new
(
"province"
,
_
(
"Voivodeship"
),
0
);
purple_request_field_group_add_field
(
group
,
field
);
for
(
i
=
0
;
i
<
ggp_pubdir_provinces_count
;
i
++
)
{
purple_request_field_choice_add
(
field
,
ggp_pubdir_provinces
[
i
],
GINT_TO_POINTER
(
i
));
if
(
record
&&
i
==
record
->
province
)
{
purple_request_field_choice_set_value
(
field
,
GINT_TO_POINTER
(
i
));
purple_request_field_choice_set_default_value
(
field
,
GINT_TO_POINTER
(
i
));
}
}
purple_request_fields
(
gc
,
_
(
"Set User Info"
),
_
(
"Set User Info"
),
NULL
,
fields
,
_
(
"OK"
),
G_CALLBACK
(
ggp_pubdir_set_info_request
),
_
(
"Cancel"
),
NULL
,
purple_request_cpar_from_connection
(
gc
),
gc
);
}
void
ggp_pubdir_set_info
(
PurpleConnection
*
gc
)
{
ggp_pubdir_get_info
(
gc
,
ggp_str_to_uin
(
purple_account_get_username
(
purple_connection_get_account
(
gc
))),
ggp_pubdir_set_info_dialog
,
NULL
);
}