| 23 #include <libsoup/soup-message.h> |
23 #include <libsoup/soup-message.h> |
| 24 #include <libsoup/soup-session.h> |
24 #include <libsoup/soup-session.h> |
| 25 |
25 |
| 26 #include "purplesatoriconnection.h" |
26 #include "purplesatoriconnection.h" |
| 27 #include "purplesatoriplugin.h" |
27 #include "purplesatoriplugin.h" |
| |
28 #include "purplesatoriprotocolconversation.h" |
| 28 #include "satorimessage.h" |
29 #include "satorimessage.h" |
| 29 #include "satoritypes.h" |
30 #include "satoritypes.h" |
| 30 #include "satoriapi.h" |
31 #include "satoriapi.h" |
| 31 |
32 |
| 32 /****************************************************************************** |
33 /****************************************************************************** |
| 151 if (!PURPLE_IS_CONTACT(contact)) { |
152 if (!PURPLE_IS_CONTACT(contact)) { |
| 152 contact = purple_contact_new(acc, user->id); |
153 contact = purple_contact_new(acc, user->id); |
| 153 found = FALSE; |
154 found = FALSE; |
| 154 } |
155 } |
| 155 |
156 |
| 156 purple_contact_info_set_display_name( |
157 if (user->nick) |
| 157 PURPLE_CONTACT_INFO(contact), |
158 purple_contact_info_set_display_name( |
| 158 user->nick ? user->nick : user->name); |
159 PURPLE_CONTACT_INFO(contact), user->nick); |
| |
160 else if (user->name) |
| |
161 purple_contact_info_set_display_name( |
| |
162 PURPLE_CONTACT_INFO(contact), user->name); |
| 159 |
163 |
| 160 PurplePresence *presence = purple_contact_info_get_presence( |
164 PurplePresence *presence = purple_contact_info_get_presence( |
| 161 PURPLE_CONTACT_INFO(contact)); |
165 PURPLE_CONTACT_INFO(contact)); |
| 162 purple_presence_set_primitive(presence, |
166 purple_presence_set_primitive(presence, |
| 163 PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); |
167 PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); |
| 250 if (next) |
254 if (next) |
| 251 JBA(b, "next", next); |
255 JBA(b, "next", next); |
| 252 JB_END_OBJ(data, b); |
256 JB_END_OBJ(data, b); |
| 253 } |
257 } |
| 254 |
258 |
| 255 SoupMessage *msg = satori_message_new( |
259 SoupMessage *msg = SATORI_ENDPOINT(con, "/friend.list"); |
| 256 "POST", SATORI_ENDPOINT("/v1/friend.list")); |
|
| 257 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
260 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
| 258 |
261 |
| 259 purple_satori_connection_send_and_read_async( |
262 purple_satori_connection_send_and_read_async( |
| 260 con, msg, 0, NULL, |
263 con, msg, 0, NULL, |
| 261 (GAsyncReadyCallback) satori_on_buddy_contacts_resp, |
264 (GAsyncReadyCallback) satori_on_buddy_contacts_resp, |
| 335 if (next) |
338 if (next) |
| 336 JBA(b, "next", next); |
339 JBA(b, "next", next); |
| 337 JB_END_OBJ(data, b); |
340 JB_END_OBJ(data, b); |
| 338 } |
341 } |
| 339 |
342 |
| 340 SoupMessage *msg = satori_message_new( |
343 SoupMessage *msg = SATORI_ENDPOINT(con, "/channel.list"); |
| 341 "POST", SATORI_ENDPOINT("/v1/channel.list")); |
|
| 342 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
344 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
| 343 |
345 |
| 344 purple_satori_connection_send_and_read_async( |
346 purple_satori_connection_send_and_read_async( |
| 345 con, msg, 0, NULL, |
347 con, msg, 0, NULL, |
| 346 (GAsyncReadyCallback) satori_on_guild_channels_resp, |
348 (GAsyncReadyCallback) satori_on_guild_channels_resp, |
| 410 if (next) |
412 if (next) |
| 411 JBA(b, "next", next); |
413 JBA(b, "next", next); |
| 412 JB_END_OBJ(data, b); |
414 JB_END_OBJ(data, b); |
| 413 } |
415 } |
| 414 |
416 |
| 415 SoupMessage *msg = satori_message_new( |
417 SoupMessage *msg = SATORI_ENDPOINT(con, "/guild.list"); |
| 416 "POST", SATORI_ENDPOINT("/v1/guild.list")); |
|
| 417 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
418 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
| 418 |
419 |
| 419 purple_satori_connection_send_and_read_async( |
420 purple_satori_connection_send_and_read_async( |
| 420 con, msg, 0, NULL, |
421 con, msg, 0, NULL, |
| 421 (GAsyncReadyCallback) satori_on_guild_list_resp, |
422 (GAsyncReadyCallback) satori_on_guild_list_resp, |
| 422 PURPLE_SATORI_CONNECTION(con)); |
423 PURPLE_SATORI_CONNECTION(con)); |
| 423 |
424 |
| 424 g_object_unref(msg); |
425 g_object_unref(msg); |
| 425 g_bytes_unref(data); |
426 g_bytes_unref(data); |
| 426 } |
427 } |
| |
428 |
| |
429 /****************************************************************************** |
| |
430 * DM Creation |
| |
431 *****************************************************************************/ |
| 427 |
432 |
| 428 typedef struct { |
433 typedef struct { |
| 429 PurpleSatoriConnection *con; |
434 PurpleSatoriConnection *con; |
| 430 SatoriUser user; |
435 SatoriUser user; |
| 431 GTask *task; |
436 GTask *task; |
| 495 JB_BEGIN_OBJ(b); |
500 JB_BEGIN_OBJ(b); |
| 496 JBA(b, "user_id", user->id); |
501 JBA(b, "user_id", user->id); |
| 497 JB_END_OBJ(data, b); |
502 JB_END_OBJ(data, b); |
| 498 } |
503 } |
| 499 |
504 |
| 500 SoupMessage *msg = satori_message_new( |
505 SoupMessage *msg = SATORI_ENDPOINT(con, "/user.channel.create"); |
| 501 "POST", SATORI_ENDPOINT("/v1/user.channel.create")); |
|
| 502 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
506 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
| 503 |
507 |
| 504 SatoriOnDmChannelData *dptr = g_new0(SatoriOnDmChannelData, 1); |
508 SatoriOnDmChannelData *dptr = g_new0(SatoriOnDmChannelData, 1); |
| 505 dptr->user.name = dptr->user.nick = g_strdup(user->name); |
509 dptr->user.name = dptr->user.nick = g_strdup(user->name); |
| 506 dptr->user.id = g_strdup(user->id); |
510 dptr->user.id = g_strdup(user->id); |
| 513 dptr); |
517 dptr); |
| 514 |
518 |
| 515 g_object_unref(msg); |
519 g_object_unref(msg); |
| 516 g_bytes_unref(data); |
520 g_bytes_unref(data); |
| 517 } |
521 } |
| |
522 |
| |
523 /****************************************************************************** |
| |
524 * Message Routines |
| |
525 *****************************************************************************/ |
| |
526 |
| |
527 typedef struct { |
| |
528 PurpleConversation *conversation; |
| |
529 PurpleMessage *message; |
| |
530 GTask *task; |
| |
531 } SatoriSendMessageData; |
| |
532 |
| |
533 static void |
| |
534 satori_on_message_sent(SoupSession *session, |
| |
535 GAsyncResult *res, |
| |
536 SatoriSendMessageData *dptr) |
| |
537 { |
| |
538 GError *error = NULL; |
| |
539 GBytes *resp = soup_session_send_and_read_finish(session, res, &error); |
| |
540 |
| |
541 if (error) { |
| |
542 purple_debug_error("satori", |
| |
543 "create_dm_channel failed: %s", |
| |
544 error->message); |
| |
545 if (resp) |
| |
546 g_bytes_unref(resp); |
| |
547 |
| |
548 g_task_return_error(dptr->task, error); |
| |
549 goto cleanup; |
| |
550 } |
| |
551 |
| |
552 gsize sz; |
| |
553 const gchar *ptr = g_bytes_get_data(resp, &sz); |
| |
554 |
| |
555 JsonParser *parser = json_parser_new(); |
| |
556 if (!json_parser_load_from_data(parser, ptr, sz, NULL)) { |
| |
557 purple_debug_warning("satori", "bad json received from api"); |
| |
558 g_task_return_new_error_literal(dptr->task, PURPLE_SATORI_DOMAIN, 0, |
| |
559 "bad json received from api"); |
| |
560 goto cleanup; |
| |
561 } |
| |
562 |
| |
563 /* Initialize ID */ |
| |
564 |
| |
565 JsonArray *root = json_node_get_array(json_parser_get_root(parser)); |
| |
566 JsonObject *msg_obj = json_array_get_object_element(root, 0); |
| |
567 const gchar *id = json_object_get_string_member_with_default( |
| |
568 msg_obj, "id", NULL); |
| |
569 |
| |
570 if (!id) { |
| |
571 g_task_return_new_error_literal(dptr->task, PURPLE_SATORI_DOMAIN, 0, |
| |
572 "message not found"); |
| |
573 goto cleanup; |
| |
574 } |
| |
575 |
| |
576 purple_message_set_id(dptr->message, id); |
| |
577 purple_message_set_delivered(dptr->message, TRUE); |
| |
578 |
| |
579 /* Initialize created_time */ |
| |
580 |
| |
581 time_t created_at = json_object_get_int_member_with_default( |
| |
582 msg_obj, "created_at", 0) / 1000; /* timestamp in mS */ |
| |
583 |
| |
584 if (created_at) { |
| |
585 GDateTime *ts = g_date_time_new_from_unix_local(created_at); |
| |
586 purple_message_set_delivered_at(dptr->message, ts); |
| |
587 g_date_time_unref(ts); |
| |
588 } |
| |
589 |
| |
590 g_task_return_boolean(dptr->task, TRUE); |
| |
591 g_object_unref(parser); |
| |
592 cleanup: |
| |
593 g_clear_object(&dptr->task); |
| |
594 g_free(dptr); |
| |
595 } |
| |
596 |
| |
597 void |
| |
598 satori_send_message(PurpleSatoriConnection *con, |
| |
599 PurpleConversation *conversation, |
| |
600 PurpleMessage *message, |
| |
601 const gchar *content, |
| |
602 GTask *task) |
| |
603 { |
| |
604 GBytes *data = NULL; |
| |
605 |
| |
606 { |
| |
607 JB_BEGIN_OBJ(b); |
| |
608 JBA(b, "channel_id", purple_conversation_get_id(conversation)); |
| |
609 JBA(b, "content", content); |
| |
610 JB_END_OBJ(data, b); |
| |
611 } |
| |
612 |
| |
613 SoupMessage *msg = SATORI_ENDPOINT(con, "/message.create"); |
| |
614 soup_message_set_request_body_from_bytes(msg, "application/json", data); |
| |
615 |
| |
616 SatoriSendMessageData *dptr = g_new0(SatoriSendMessageData, 1); |
| |
617 dptr->conversation = conversation; |
| |
618 dptr->message = message; |
| |
619 dptr->task = task; |
| |
620 |
| |
621 purple_satori_connection_send_and_read_async( |
| |
622 con, msg, 0, NULL, |
| |
623 (GAsyncReadyCallback) satori_on_message_sent, |
| |
624 dptr); |
| |
625 |
| |
626 g_object_unref(msg); |
| |
627 g_bytes_unref(data); |
| |
628 } |