comparison libpurple/protocols/gg/gg.c @ 31917:64d1be114e02

Recently I found out a small issue: if another user changes it's avatar, we don't get it updated. New avatar is visible after our reconnect, or after this other user status change. I found out, that we get these updates in XML event packet, but we don't handle them. XML events can contain: - GGLive messages (I think, it's something like tweeter service) - notifications about avatar changes - notifications about user's new blog entries - graphical statuses (I hope we will NOT support this one) Detailed information (in Polish): http://toxygen.net/libgadu/protocol/#ch1.13 I have implemented general support for XML events, so we could provide support for new !GaduGadu features in the future. Also, I have fixed that small issue, by implementing avatar change notifications, provided by these events. committer: John Bailey <rekkanoryo@rekkanoryo.org>
author tomkiewicz@o2.pl
date Sat, 16 Apr 2011 15:35:53 +0000
parents 566bed5c02f2
children b2daa6e51596
comparison
equal deleted inserted replaced
31916:26cda93eb18f 31917:64d1be114e02
1042 xmlnode_free(xml); 1042 xmlnode_free(xml);
1043 g_free(bigavatar); 1043 g_free(bigavatar);
1044 } 1044 }
1045 1045
1046 /** 1046 /**
1047 * Try to update avatar of the buddy.
1048 *
1049 * @param gc PurpleConnection
1050 * @param uin UIN of the buddy.
1051 */
1052 static void ggp_update_buddy_avatar(PurpleConnection *gc, uin_t uin)
1053 {
1054 gchar *avatarurl;
1055 PurpleUtilFetchUrlData *url_data;
1056
1057 purple_debug_info("gg", "ggp_update_buddy_avatar(gc, %u)\n", uin);
1058
1059 avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%u/0.xml", uin);
1060
1061 url_data = purple_util_fetch_url_request_len_with_account(
1062 purple_connection_get_account(gc), avatarurl, TRUE,
1063 "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1,
1064 gg_get_avatar_url_cb, gc);
1065
1066 g_free(avatarurl);
1067 }
1068
1069 /**
1047 * Handle change of the status of the buddy. 1070 * Handle change of the status of the buddy.
1048 * 1071 *
1049 * @param gc PurpleConnection 1072 * @param gc PurpleConnection
1050 * @param uin UIN of the buddy. 1073 * @param uin UIN of the buddy.
1051 * @param status ID of the status. 1074 * @param status ID of the status.
1054 static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin, 1077 static void ggp_generic_status_handler(PurpleConnection *gc, uin_t uin,
1055 int status, const char *descr) 1078 int status, const char *descr)
1056 { 1079 {
1057 gchar *from; 1080 gchar *from;
1058 const char *st; 1081 const char *st;
1059 gchar *avatarurl; 1082
1060 PurpleUtilFetchUrlData *url_data; 1083 ggp_update_buddy_avatar(gc, uin);
1061 1084
1062 from = g_strdup_printf("%u", uin); 1085 from = g_strdup_printf("%u", uin);
1063 avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%s/0.xml", from);
1064
1065 url_data = purple_util_fetch_url_request_len_with_account(
1066 purple_connection_get_account(gc), avatarurl, TRUE,
1067 "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1,
1068 gg_get_avatar_url_cb, gc);
1069
1070 g_free(avatarurl);
1071 1086
1072 switch (status) { 1087 switch (status) {
1073 case GG_STATUS_NOT_AVAIL: 1088 case GG_STATUS_NOT_AVAIL:
1074 case GG_STATUS_NOT_AVAIL_DESCR: 1089 case GG_STATUS_NOT_AVAIL_DESCR:
1075 st = purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE); 1090 st = purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE);
1612 else 1627 else
1613 serv_got_typing_stopped(gc, from); 1628 serv_got_typing_stopped(gc, from);
1614 g_free(from); 1629 g_free(from);
1615 } 1630 }
1616 1631
1632 /**
1633 * Handling of XML events.
1634 *
1635 * @param gc PurpleConnection.
1636 * @param data Raw XML contents.
1637 *
1638 * @see http://toxygen.net/libgadu/protocol/#ch1.13
1639 */
1640 static void ggp_xml_event_handler(PurpleConnection *gc, char *data)
1641 {
1642 xmlnode *xml = NULL;
1643 xmlnode *xmlnode_next_event;
1644
1645 xml = xmlnode_from_str(data, -1);
1646 if (xml == NULL)
1647 goto out;
1648
1649 xmlnode_next_event = xmlnode_get_child(xml, "event");
1650 while (xmlnode_next_event != NULL)
1651 {
1652 xmlnode *xmlnode_current_event = xmlnode_next_event;
1653
1654 xmlnode *xmlnode_type;
1655 char *event_type_raw;
1656 int event_type = 0;
1657
1658 xmlnode *xmlnode_sender;
1659 char *event_sender_raw;
1660 uin_t event_sender = 0;
1661
1662 xmlnode_next_event = xmlnode_get_next_twin(xmlnode_next_event);
1663
1664 xmlnode_type = xmlnode_get_child(xmlnode_current_event, "type");
1665 if (xmlnode_type == NULL)
1666 continue;
1667 event_type_raw = xmlnode_get_data(xmlnode_type);
1668 if (event_type_raw != NULL)
1669 event_type = atoi(event_type_raw);
1670 g_free(event_type_raw);
1671
1672 xmlnode_sender = xmlnode_get_child(xmlnode_current_event, "sender");
1673 if (xmlnode_sender != NULL)
1674 {
1675 event_sender_raw = xmlnode_get_data(xmlnode_sender);
1676 if (event_sender_raw != NULL)
1677 event_sender = ggp_str_to_uin(event_sender_raw);
1678 g_free(event_sender_raw);
1679 }
1680
1681 switch (event_type)
1682 {
1683 case 28: /* avatar update */
1684 purple_debug_info("gg",
1685 "ggp_xml_event_handler: avatar updated (uid: %u)\n",
1686 event_sender);
1687 ggp_update_buddy_avatar(gc, event_sender);
1688 break;
1689 default:
1690 purple_debug_error("gg",
1691 "ggp_xml_event_handler: unsupported event type=%d from=%u\n",
1692 event_type, event_sender);
1693 }
1694 }
1695
1696 out:
1697 if (xml)
1698 xmlnode_free(xml);
1699 }
1700
1617 static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond) 1701 static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond)
1618 { 1702 {
1619 PurpleConnection *gc = _gc; 1703 PurpleConnection *gc = _gc;
1620 GGPInfo *info = gc->proto_data; 1704 GGPInfo *info = gc->proto_data;
1621 struct gg_event *ev; 1705 struct gg_event *ev;
1728 ggp_pubdir_reply_handler(gc, ev->event.pubdir50); 1812 ggp_pubdir_reply_handler(gc, ev->event.pubdir50);
1729 break; 1813 break;
1730 case GG_EVENT_TYPING_NOTIFICATION: 1814 case GG_EVENT_TYPING_NOTIFICATION:
1731 ggp_typing_notification_handler(gc, ev->event.typing_notification.uin, 1815 ggp_typing_notification_handler(gc, ev->event.typing_notification.uin,
1732 ev->event.typing_notification.length); 1816 ev->event.typing_notification.length);
1817 break;
1818 case GG_EVENT_XML_EVENT:
1819 purple_debug_info("gg", "GG_EVENT_XML_EVENT\n");
1820 ggp_xml_event_handler(gc, ev->event.xml_event.data);
1733 break; 1821 break;
1734 default: 1822 default:
1735 purple_debug_error("gg", 1823 purple_debug_error("gg",
1736 "unsupported event type=%d\n", ev->type); 1824 "unsupported event type=%d\n", ev->type);
1737 break; 1825 break;