libpurple/protocols/facebook/api.c

changeset 38397
046138091ee2
parent 38396
a7a919217259
child 38398
a2fe2e8fe876
equal deleted inserted replaced
38396:a7a919217259 38397:046138091ee2
1482 1482
1483 1483
1484 static GSList * 1484 static GSList *
1485 fb_api_cb_publish_ms_new_message(FbApi *api, JsonNode *root, GSList *msgs, GError **error); 1485 fb_api_cb_publish_ms_new_message(FbApi *api, JsonNode *root, GSList *msgs, GError **error);
1486 1486
1487 static GSList *
1488 fb_api_cb_publish_ms_event(FbApi *api, JsonNode *root, GSList *events, FbApiEventType type, GError **error);
1489
1487 static void 1490 static void
1488 fb_api_cb_publish_ms(FbApi *api, GByteArray *pload) 1491 fb_api_cb_publish_ms(FbApi *api, GByteArray *pload)
1489 { 1492 {
1490 const gchar *data; 1493 const gchar *data;
1491 FbApiPrivate *priv = api->priv; 1494 FbApiPrivate *priv = api->priv;
1493 FbThrift *thft; 1496 FbThrift *thft;
1494 gchar *stoken; 1497 gchar *stoken;
1495 GError *err = NULL; 1498 GError *err = NULL;
1496 GList *elms, *l; 1499 GList *elms, *l;
1497 GSList *msgs = NULL; 1500 GSList *msgs = NULL;
1501 GSList *events = NULL;
1498 guint size; 1502 guint size;
1499 JsonNode *root; 1503 JsonNode *root;
1500 JsonNode *node; 1504 JsonNode *node;
1501 JsonArray *arr; 1505 JsonArray *arr;
1506
1507 static const struct {
1508 const gchar *member;
1509 FbApiEventType type;
1510 gboolean is_message;
1511 } event_types[] = {
1512 {"deltaNewMessage", 0, 1},
1513 {"deltaThreadName", FB_API_EVENT_TYPE_THREAD_TOPIC, 0},
1514 {"deltaParticipantsAddedToGroupThread", FB_API_EVENT_TYPE_THREAD_USER_ADDED, 0},
1515 {"deltaParticipantLeftGroupThread", FB_API_EVENT_TYPE_THREAD_USER_REMOVED, 0},
1516 };
1502 1517
1503 /* Read identifier string (for Facebook employees) */ 1518 /* Read identifier string (for Facebook employees) */
1504 thft = fb_thrift_new(pload, 0); 1519 thft = fb_thrift_new(pload, 0);
1505 fb_thrift_read_str(thft, NULL); 1520 fb_thrift_read_str(thft, NULL);
1506 size = fb_thrift_get_pos(thft); 1521 size = fb_thrift_get_pos(thft);
1540 1555
1541 arr = fb_json_node_get_arr(root, "$.deltas", NULL); 1556 arr = fb_json_node_get_arr(root, "$.deltas", NULL);
1542 elms = json_array_get_elements(arr); 1557 elms = json_array_get_elements(arr);
1543 1558
1544 for (l = elms; l != NULL; l = l->next) { 1559 for (l = elms; l != NULL; l = l->next) {
1560 guint i = 0;
1545 JsonObject *o = json_node_get_object(l->data); 1561 JsonObject *o = json_node_get_object(l->data);
1546 if ((node = json_object_get_member(o, "deltaNewMessage"))) { 1562
1547 msgs = fb_api_cb_publish_ms_new_message(api, node, msgs, &err); 1563 for (i = 0; i < G_N_ELEMENTS(event_types); i++) {
1548 } 1564 if ((node = json_object_get_member(o, event_types[i].member))) {
1565 if (event_types[i].is_message) {
1566 msgs = fb_api_cb_publish_ms_new_message(
1567 api, node, msgs, &err
1568 );
1569 } else {
1570 events = fb_api_cb_publish_ms_event(
1571 api, node, events, event_types[i].type, &err
1572 );
1573 }
1574 }
1575 }
1576
1549 if (G_UNLIKELY(err != NULL)) { 1577 if (G_UNLIKELY(err != NULL)) {
1550 break; 1578 break;
1551 } 1579 }
1552 } 1580 }
1553 1581
1554 g_list_free(elms); 1582 g_list_free(elms);
1555 json_array_unref(arr); 1583 json_array_unref(arr);
1556 1584
1557 if (G_LIKELY(err == NULL)) { 1585 if (G_LIKELY(err == NULL)) {
1558 msgs = g_slist_reverse(msgs); 1586 if (msgs) {
1559 g_signal_emit_by_name(api, "messages", msgs); 1587 msgs = g_slist_reverse(msgs);
1588 g_signal_emit_by_name(api, "messages", msgs);
1589 }
1590
1591 if (events) {
1592 events = g_slist_reverse(events);
1593 g_signal_emit_by_name(api, "events", events);
1594 }
1560 } else { 1595 } else {
1561 fb_api_error_emit(api, err); 1596 fb_api_error_emit(api, err);
1562 } 1597 }
1563 1598
1564 g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free); 1599 g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free);
1600 g_slist_free_full(events, (GDestroyNotify) fb_api_event_free);
1565 json_node_free(root); 1601 json_node_free(root);
1566 } 1602 }
1567 1603
1568 static GSList * 1604 static GSList *
1569 fb_api_cb_publish_ms_new_message(FbApi *api, JsonNode *root, GSList *msgs, GError **error) 1605 fb_api_cb_publish_ms_new_message(FbApi *api, JsonNode *root, GSList *msgs, GError **error)
1662 beach: 1698 beach:
1663 g_object_unref(values); 1699 g_object_unref(values);
1664 return msgs; 1700 return msgs;
1665 } 1701 }
1666 1702
1703 static GSList *
1704 fb_api_cb_publish_ms_event(FbApi *api, JsonNode *root, GSList *events, FbApiEventType type, GError **error)
1705 {
1706 FbApiEvent *event;
1707 FbJsonValues *values = NULL;
1708 FbJsonValues *values_inner = NULL;
1709 GError *err = NULL;
1710
1711 values = fb_json_values_new(root);
1712 fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
1713 "$.messageMetadata.threadKey.threadFbId");
1714 fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
1715 "$.messageMetadata.actorFbId");
1716
1717 switch (type) {
1718 case FB_API_EVENT_TYPE_THREAD_TOPIC:
1719 fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
1720 "$.name");
1721 break;
1722
1723 case FB_API_EVENT_TYPE_THREAD_USER_ADDED:
1724 values_inner = fb_json_values_new(root);
1725
1726 fb_json_values_add(values_inner, FB_JSON_TYPE_INT, FALSE,
1727 "$.userFbId");
1728
1729 /* use the text field for the full name */
1730 fb_json_values_add(values_inner, FB_JSON_TYPE_STR, FALSE,
1731 "$.fullName");
1732
1733 fb_json_values_set_array(values_inner, FALSE,
1734 "$.addedParticipants");
1735 break;
1736
1737 case FB_API_EVENT_TYPE_THREAD_USER_REMOVED:
1738 fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE,
1739 "$.leftParticipantFbId");
1740
1741 /* use the text field for the kick message */
1742 fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE,
1743 "$.messageMetadata.adminText");
1744 break;
1745 }
1746
1747 fb_json_values_update(values, &err);
1748
1749 event = fb_api_event_dup(NULL, FALSE);
1750 event->type = type;
1751 event->tid = fb_json_values_next_int(values, 0);
1752 event->uid = fb_json_values_next_int(values, 0);
1753
1754 if (type == FB_API_EVENT_TYPE_THREAD_TOPIC) {
1755 event->text = fb_json_values_next_str_dup(values, NULL);
1756 } else if (type == FB_API_EVENT_TYPE_THREAD_USER_REMOVED) {
1757 /* overwrite actor with subject */
1758 event->uid = fb_json_values_next_int(values, 0);
1759 event->text = fb_json_values_next_str_dup(values, NULL);
1760 } else if (type == FB_API_EVENT_TYPE_THREAD_USER_ADDED) {
1761
1762 while (fb_json_values_update(values_inner, &err)) {
1763 FbApiEvent *devent = fb_api_event_dup(event, FALSE);
1764
1765 devent->uid = fb_json_values_next_int(values_inner, 0);
1766 devent->text = fb_json_values_next_str_dup(values_inner, NULL);
1767
1768 events = g_slist_prepend(events, devent);
1769 }
1770 fb_api_event_free(event);
1771 event = NULL;
1772 g_object_unref(values_inner);
1773 }
1774
1775 g_object_unref(values);
1776
1777 if (G_UNLIKELY(err != NULL)) {
1778 g_propagate_error(error, err);
1779 } else if (event) {
1780 events = g_slist_prepend(events, event);
1781 }
1782
1783 return events;
1784 }
1785
1667 static void 1786 static void
1668 fb_api_cb_publish_pt(FbThrift *thft, GSList **press, GError **error) 1787 fb_api_cb_publish_pt(FbThrift *thft, GSList **press, GError **error)
1669 { 1788 {
1670 FbApiPresence *pres; 1789 FbApiPresence *pres;
1671 FbThriftType type; 1790 FbThriftType type;

mercurial