From a97d77f33211e1a97b74fc0692279829de1f9d1a Mon Sep 17 00:00:00 2001 From: Tony Olagbaiye Date: Mon, 28 Jun 2021 02:17:02 +0100 Subject: [PATCH] cleanup --- Makefile | 8 +- api/message/slack-api-message-bot-message.c | 155 -- api/message/slack-api-message-bot-message.h | 12 - api/message/slack-api-message-me-message.c | 102 - api/message/slack-api-message-me-message.h | 12 - .../slack-api-message-message-changed.c | 104 - .../slack-api-message-message-changed.h | 12 - .../slack-api-message-slackbot-response.c | 98 - .../slack-api-message-slackbot-response.h | 12 - .../slack-api-message-thread-broadcast.c | 99 - .../slack-api-message-thread-broadcast.h | 12 - api/message/slack-api-message-unimplemented.c | 50 - api/message/slack-api-message-unimplemented.h | 12 - api/slack-api-error.c | 63 - api/slack-api-error.h | 11 - api/slack-api-hello.c | 54 - api/slack-api-hello.h | 11 - api/slack-api-message.c | 240 --- api/slack-api-message.h | 13 - api/slack-api-user-typing.c | 67 - api/slack-api-user-typing.h | 11 - xmpp-command.c => command.c | 4 +- xmpp-command.h => command.h | 6 +- xmpp-config.c => config.c | 6 +- xmpp-config.h => config.h | 8 +- xmpp-connection.c => connection.c | 8 +- xmpp-connection.h => connection.h | 6 +- xmpp.c => plugin.c | 12 +- xmpp.h => plugin.h | 10 +- request/slack-request-bots-info.c | 272 --- request/slack-request-bots-info.h | 12 - request/slack-request-channels-list.c | 431 ----- request/slack-request-channels-list.h | 12 - request/slack-request-chat-memessage.c | 270 --- request/slack-request-chat-memessage.h | 13 - request/slack-request-chat-postmessage.c | 271 --- request/slack-request-chat-postmessage.h | 13 - request/slack-request-conversations-members.c | 330 ---- request/slack-request-conversations-members.h | 13 - request/slack-request-emoji-list.c | 287 --- request/slack-request-emoji-list.h | 12 - request/slack-request-users-list.c | 375 ---- request/slack-request-users-list.h | 12 - slack-buffer.c | 164 -- slack-buffer.h | 27 - slack-channel.c | 642 ------- slack-channel.h | 147 -- slack-completion.c | 162 -- slack-completion.h | 10 - slack-emoji.c | 289 --- slack-emoji.h | 29 - slack-emoji.inc | 1702 ----------------- slack-input.c | 77 - slack-input.h | 12 - slack-message.c | 249 --- slack-message.h | 13 - slack-oauth.c | 245 --- slack-oauth.h | 10 - slack-request.c | 27 - slack-request.h | 29 - slack-teaminfo.c | 348 ---- slack-teaminfo.h | 20 - slack-user.c | 241 --- slack-user.h | 74 - slack-workspace.c | 972 ---------- slack-workspace.h | 95 - 66 files changed, 34 insertions(+), 9091 deletions(-) delete mode 100644 api/message/slack-api-message-bot-message.c delete mode 100644 api/message/slack-api-message-bot-message.h delete mode 100644 api/message/slack-api-message-me-message.c delete mode 100644 api/message/slack-api-message-me-message.h delete mode 100644 api/message/slack-api-message-message-changed.c delete mode 100644 api/message/slack-api-message-message-changed.h delete mode 100644 api/message/slack-api-message-slackbot-response.c delete mode 100644 api/message/slack-api-message-slackbot-response.h delete mode 100644 api/message/slack-api-message-thread-broadcast.c delete mode 100644 api/message/slack-api-message-thread-broadcast.h delete mode 100644 api/message/slack-api-message-unimplemented.c delete mode 100644 api/message/slack-api-message-unimplemented.h delete mode 100644 api/slack-api-error.c delete mode 100644 api/slack-api-error.h delete mode 100644 api/slack-api-hello.c delete mode 100644 api/slack-api-hello.h delete mode 100644 api/slack-api-message.c delete mode 100644 api/slack-api-message.h delete mode 100644 api/slack-api-user-typing.c delete mode 100644 api/slack-api-user-typing.h rename xmpp-command.c => command.c (99%) rename xmpp-command.h => command.h (70%) rename xmpp-config.c => config.c (99%) rename xmpp-config.h => config.h (95%) rename xmpp-connection.c => connection.c (98%) rename xmpp-connection.h => connection.h (85%) rename xmpp.c => plugin.c (93%) rename xmpp.h => plugin.h (66%) delete mode 100644 request/slack-request-bots-info.c delete mode 100644 request/slack-request-bots-info.h delete mode 100644 request/slack-request-channels-list.c delete mode 100644 request/slack-request-channels-list.h delete mode 100644 request/slack-request-chat-memessage.c delete mode 100644 request/slack-request-chat-memessage.h delete mode 100644 request/slack-request-chat-postmessage.c delete mode 100644 request/slack-request-chat-postmessage.h delete mode 100644 request/slack-request-conversations-members.c delete mode 100644 request/slack-request-conversations-members.h delete mode 100644 request/slack-request-emoji-list.c delete mode 100644 request/slack-request-emoji-list.h delete mode 100644 request/slack-request-users-list.c delete mode 100644 request/slack-request-users-list.h delete mode 100644 slack-buffer.c delete mode 100644 slack-buffer.h delete mode 100644 slack-channel.c delete mode 100644 slack-channel.h delete mode 100644 slack-completion.c delete mode 100644 slack-completion.h delete mode 100644 slack-emoji.c delete mode 100644 slack-emoji.h delete mode 100644 slack-emoji.inc delete mode 100644 slack-input.c delete mode 100644 slack-input.h delete mode 100644 slack-message.c delete mode 100644 slack-message.h delete mode 100644 slack-oauth.c delete mode 100644 slack-oauth.h delete mode 100644 slack-request.c delete mode 100644 slack-request.h delete mode 100644 slack-teaminfo.c delete mode 100644 slack-teaminfo.h delete mode 100644 slack-user.c delete mode 100644 slack-user.h delete mode 100644 slack-workspace.c delete mode 100644 slack-workspace.h diff --git a/Makefile b/Makefile index 3b28f64..704f6b1 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,10 @@ PREFIX ?= /usr/local LIBDIR ?= $(PREFIX)/lib INSTALL ?= /usr/bin/install -SRCS=xmpp.c \ - xmpp-command.c \ - xmpp-config.c \ - xmpp-connection.c \ +SRCS=plugin.c \ + command.c \ + config.c \ + connection.c \ DEPS=json-c/libjson-c.a OLDSRCS=slack.c \ diff --git a/api/message/slack-api-message-bot-message.c b/api/message/slack-api-message-bot-message.c deleted file mode 100644 index 5a7b488..0000000 --- a/api/message/slack-api-message-bot-message.c +++ /dev/null @@ -1,155 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "../../weechat-plugin.h" -#include "../../slack.h" -#include "../../slack-workspace.h" -#include "../../slack-message.h" -#include "../../slack-api.h" -#include "../../slack-channel.h" -#include "../../slack-user.h" -#include "../slack-api-message.h" -#include "slack-api-message-bot-message.h" - -static const char *subtype = "bot_message"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %smessage.%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), subtype, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_message_bot_message_handle(struct t_slack_workspace *workspace, - const char *channel, const char *bot_id, - const char *username, const char *text, - const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - struct t_slack_channel_typing *ptr_typing; - - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; /* silently ignore if channel hasn't been loaded yet */ - ptr_user = slack_user_bot_search(workspace, bot_id); - if (!ptr_user) - return 1; /* silently ignore if bot user hasn't been loaded yet */ - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message,slack_bot_message", - _("%s%s"), - slack_user_as_prefix(workspace, ptr_user, username), - message); - free(message); - - ptr_typing = slack_channel_typing_search(ptr_channel, - ptr_user->profile.display_name); - if (ptr_typing) - { - slack_channel_typing_free(ptr_channel, ptr_typing); - slack_channel_typing_cb(ptr_channel, NULL, 0); - } - - return 1; -} - -int slack_api_message_slackbot_message_handle(struct t_slack_workspace *workspace, - const char *channel, const char *user, - const char *text, const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - struct t_slack_channel_typing *ptr_typing; - - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; /* silently ignore if channel hasn't been loaded yet */ - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; /* silently ignore if slackbot user hasn't been loaded yet */ - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message,slack_slackbot_message", - _("%s%s"), - slack_user_as_prefix(workspace, ptr_user, user), - message); - free(message); - - ptr_typing = slack_channel_typing_search(ptr_channel, - ptr_user->profile.display_name); - if (ptr_typing) - { - slack_channel_typing_free(ptr_channel, ptr_typing); - slack_channel_typing_cb(ptr_channel, NULL, 0); - } - - return 1; -} - -int slack_api_message_bot_message(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *channel, *bot_id, *username, *user, *text, *ts; - channel = json_object_object_get(message, "channel"); - if (!json_valid(channel, workspace)) - return 0; - - username = json_object_object_get(message, "username"); - if (!json_valid(username, workspace)) - return 0; - - text = json_object_object_get(message, "text"); - if (!json_valid(text, workspace)) - return 0; - - ts = json_object_object_get(message, "ts"); - if (!json_valid(ts, workspace)) - return 0; - - if (strcmp("slackbot", json_object_get_string(username)) == 0) - { - user = json_object_object_get(message, "user"); - if (!json_valid(user, workspace)) - return 0; - - return slack_api_message_slackbot_message_handle(workspace, - json_object_get_string(channel), - json_object_get_string(user), - json_object_get_string(text), - json_object_get_string(ts)); - } - else - { - bot_id = json_object_object_get(message, "bot_id"); - if (!json_valid(bot_id, workspace)) - return 0; - - return slack_api_message_bot_message_handle(workspace, - json_object_get_string(channel), - json_object_get_string(bot_id), - json_object_get_string(username), - json_object_get_string(text), - json_object_get_string(ts)); - } -} - diff --git a/api/message/slack-api-message-bot-message.h b/api/message/slack-api-message-bot-message.h deleted file mode 100644 index 93d55fc..0000000 --- a/api/message/slack-api-message-bot-message.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_MESSAGE_BOT_MESSAGE_H_ -#define _SLACK_API_MESSAGE_BOT_MESSAGE_H_ - -int slack_api_message_bot_message( - struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_MESSAGE_BOT_MESSAGE_H*/ diff --git a/api/message/slack-api-message-me-message.c b/api/message/slack-api-message-me-message.c deleted file mode 100644 index fcc91d1..0000000 --- a/api/message/slack-api-message-me-message.c +++ /dev/null @@ -1,102 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "../../weechat-plugin.h" -#include "../../slack.h" -#include "../../slack-workspace.h" -#include "../../slack-message.h" -#include "../../slack-api.h" -#include "../../slack-channel.h" -#include "../../slack-user.h" -#include "../slack-api-message.h" -#include "slack-api-message-me-message.h" - -static const char *subtype = "me_message"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %smessage.%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), subtype, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_message_me_message_handle(struct t_slack_workspace *workspace, - const char *channel, const char *user, - const char *text, const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - struct t_slack_channel_typing *ptr_typing; - - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; /* silently ignore if channel hasn't been loaded yet */ - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; /* silently ignore if user hasn't been loaded yet */ - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message,slack_me_message", - _("%s%s%s%s%s%s"), - weechat_prefix("action"), - slack_user_get_colour(ptr_user), - ptr_user->profile.display_name, - weechat_color("reset"), - message[0] ? " " : "", - message); - free(message); - - ptr_typing = slack_channel_typing_search(ptr_channel, - ptr_user->profile.display_name); - if (ptr_typing) - { - slack_channel_typing_free(ptr_channel, ptr_typing); - slack_channel_typing_cb(ptr_channel, NULL, 0); - } - - return 1; -} - -int slack_api_message_me_message(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *channel, *user, *text, *ts; - channel = json_object_object_get(message, "channel"); - if (!json_valid(channel, workspace)) - return 0; - - user = json_object_object_get(message, "user"); - if (!json_valid(user, workspace)) - return 0; - - text = json_object_object_get(message, "text"); - if (!json_valid(text, workspace)) - return 0; - - ts = json_object_object_get(message, "ts"); - if (!json_valid(ts, workspace)) - return 0; - - return slack_api_message_me_message_handle(workspace, - json_object_get_string(channel), - json_object_get_string(user), - json_object_get_string(text), - json_object_get_string(ts)); -} - diff --git a/api/message/slack-api-message-me-message.h b/api/message/slack-api-message-me-message.h deleted file mode 100644 index 1131898..0000000 --- a/api/message/slack-api-message-me-message.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_MESSAGE_ME_MESSAGE_H_ -#define _SLACK_API_MESSAGE_ME_MESSAGE_H_ - -int slack_api_message_me_message( - struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_MESSAGE_ME_MESSAGE_H*/ diff --git a/api/message/slack-api-message-message-changed.c b/api/message/slack-api-message-message-changed.c deleted file mode 100644 index 95b2a29..0000000 --- a/api/message/slack-api-message-message-changed.c +++ /dev/null @@ -1,104 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "../../weechat-plugin.h" -#include "../../slack.h" -#include "../../slack-workspace.h" -#include "../../slack-message.h" -#include "../../slack-api.h" -#include "../../slack-channel.h" -#include "../../slack-user.h" -#include "../slack-api-message.h" -#include "slack-api-message-message-changed.h" - -static const char *subtype = "message_changed"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %smessage.%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), subtype, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_message_message_changed_handle(struct t_slack_workspace *workspace, - json_object *root, const char *user, - const char *text, const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - struct t_slack_channel_typing *ptr_typing; - - /* - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; // silently ignore if channel hasn't been loaded yet - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; // silently ignore if user hasn't been loaded yet - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message,slack_thread_broadcast", - _("%s%s"), - slack_user_as_prefix(workspace, ptr_user, NULL), - message); - free(message); - - ptr_typing = slack_channel_typing_search(ptr_channel, - ptr_user->profile.display_name); - if (ptr_typing) - { - slack_channel_typing_free(ptr_channel, ptr_typing); - slack_channel_typing_cb(ptr_channel, NULL, 0); - } - */ - - return 1; -} - -int slack_api_message_message_changed(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *channel, *oldmsg, *user, *text, *ts; - channel = json_object_object_get(message, "channel"); - if (!json_valid(channel, workspace)) - return 0; - - oldmsg = json_object_object_get(message, "message"); - if (!json_valid(oldmsg, workspace)) - return 0; - - user = json_object_object_get(oldmsg, "user"); - if (!json_valid(user, workspace)) - return 0; - - text = json_object_object_get(message, "text"); - if (!json_valid(text, workspace)) - return 0; - - ts = json_object_object_get(message, "ts"); - if (!json_valid(ts, workspace)) - return 0; - - return slack_api_message_message_changed_handle(workspace, - json_object_get_string(channel), - json_object_get_string(user), - json_object_get_string(text), - json_object_get_string(ts)); -} - diff --git a/api/message/slack-api-message-message-changed.h b/api/message/slack-api-message-message-changed.h deleted file mode 100644 index 2fd4239..0000000 --- a/api/message/slack-api-message-message-changed.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_MESSAGE_MESSAGE_CHANGED_H_ -#define _SLACK_API_MESSAGE_MESSAGE_CHANGED_H_ - -int slack_api_message_message_changed( - struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_MESSAGE_MESSAGE_CHANGED_H*/ diff --git a/api/message/slack-api-message-slackbot-response.c b/api/message/slack-api-message-slackbot-response.c deleted file mode 100644 index 8252d28..0000000 --- a/api/message/slack-api-message-slackbot-response.c +++ /dev/null @@ -1,98 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "../../weechat-plugin.h" -#include "../../slack.h" -#include "../../slack-workspace.h" -#include "../../slack-message.h" -#include "../../slack-api.h" -#include "../../slack-channel.h" -#include "../../slack-user.h" -#include "../slack-api-message.h" -#include "slack-api-message-slackbot-response.h" - -static const char *subtype = "slackbot_response"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %smessage.%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), subtype, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_message_slackbot_response_handle(struct t_slack_workspace *workspace, - const char *channel, const char *user, - const char *text, const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - struct t_slack_channel_typing *ptr_typing; - - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; /* silently ignore if channel hasn't been loaded yet */ - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; /* silently ignore if slackbot user hasn't been loaded yet */ - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message,slack_slackbot_response", - _("%s%s"), - slack_user_as_prefix(workspace, ptr_user, "slackbot"), - message); - free(message); - - ptr_typing = slack_channel_typing_search(ptr_channel, - ptr_user->profile.display_name); - if (ptr_typing) - { - slack_channel_typing_free(ptr_channel, ptr_typing); - slack_channel_typing_cb(ptr_channel, NULL, 0); - } - - return 1; -} - -int slack_api_message_slackbot_response(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *channel, *user, *text, *ts; - channel = json_object_object_get(message, "channel"); - if (!json_valid(channel, workspace)) - return 0; - - user = json_object_object_get(message, "user"); - if (!json_valid(user, workspace)) - return 0; - - text = json_object_object_get(message, "text"); - if (!json_valid(text, workspace)) - return 0; - - ts = json_object_object_get(message, "ts"); - if (!json_valid(ts, workspace)) - return 0; - - return slack_api_message_slackbot_response_handle(workspace, - json_object_get_string(channel), - json_object_get_string(user), - json_object_get_string(text), - json_object_get_string(ts)); -} - diff --git a/api/message/slack-api-message-slackbot-response.h b/api/message/slack-api-message-slackbot-response.h deleted file mode 100644 index edab623..0000000 --- a/api/message/slack-api-message-slackbot-response.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_MESSAGE_SLACKBOT_RESPONSE_H_ -#define _SLACK_API_MESSAGE_SLACKBOT_RESPONSE_H_ - -int slack_api_message_slackbot_response( - struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_MESSAGE_SLACKBOT_RESPONSE_H*/ diff --git a/api/message/slack-api-message-thread-broadcast.c b/api/message/slack-api-message-thread-broadcast.c deleted file mode 100644 index ce59478..0000000 --- a/api/message/slack-api-message-thread-broadcast.c +++ /dev/null @@ -1,99 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "../../weechat-plugin.h" -#include "../../slack.h" -#include "../../slack-workspace.h" -#include "../../slack-message.h" -#include "../../slack-api.h" -#include "../../slack-channel.h" -#include "../../slack-user.h" -#include "../slack-api-message.h" -#include "slack-api-message-thread-broadcast.h" - -static const char *subtype = "thread_broadcast"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %smessage.%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), subtype, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_message_thread_broadcast_handle(struct t_slack_workspace *workspace, - json_object *root, const char *user, - const char *text, const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - struct t_slack_channel_typing *ptr_typing; - - /* - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; // silently ignore if channel hasn't been loaded yet - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; // silently ignore if user hasn't been loaded yet - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message,slack_thread_broadcast", - _("%s%s"), - slack_user_as_prefix(workspace, ptr_user, NULL), - message); - free(message); - - ptr_typing = slack_channel_typing_search(ptr_channel, - ptr_user->profile.display_name); - if (ptr_typing) - { - slack_channel_typing_free(ptr_channel, ptr_typing); - slack_channel_typing_cb(ptr_channel, NULL, 0); - } - */ - - return 1; -} - -int slack_api_message_thread_broadcast(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *root, *user, *text, *ts; - root = json_object_object_get(message, "root"); - if (!json_valid(root, workspace)) - return 0; - - user = json_object_object_get(message, "user"); - if (!json_valid(user, workspace)) - return 0; - - text = json_object_object_get(message, "text"); - if (!json_valid(text, workspace)) - return 0; - - ts = json_object_object_get(message, "ts"); - if (!json_valid(ts, workspace)) - return 0; - - return slack_api_message_thread_broadcast_handle(workspace, - root, json_object_get_string(user), - json_object_get_string(text), - json_object_get_string(ts)); -} - diff --git a/api/message/slack-api-message-thread-broadcast.h b/api/message/slack-api-message-thread-broadcast.h deleted file mode 100644 index ea56ce7..0000000 --- a/api/message/slack-api-message-thread-broadcast.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_MESSAGE_THREAD_BROADCAST_H_ -#define _SLACK_API_MESSAGE_THREAD_BROADCAST_H_ - -int slack_api_message_thread_broadcast( - struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_MESSAGE_THREAD_BROADCAST_H*/ diff --git a/api/message/slack-api-message-unimplemented.c b/api/message/slack-api-message-unimplemented.c deleted file mode 100644 index d9b3490..0000000 --- a/api/message/slack-api-message-unimplemented.c +++ /dev/null @@ -1,50 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "../../weechat-plugin.h" -#include "../../slack.h" -#include "../../slack-workspace.h" -#include "../../slack-api.h" -#include "../../slack-channel.h" -#include "../../slack-user.h" -#include "../slack-api-message.h" -#include "slack-api-message-unimplemented.h" - -static const char *subtype = "unimplemented"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %smessage.%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), subtype, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_message_unimplemented(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *subtype = json_object_object_get(message, "subtype"); - if (!json_valid(subtype, workspace)) - return 0; - - weechat_printf( - workspace->buffer, - _("%s%s: got unhandled message of type: message.%s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - json_object_get_string(subtype)); - - return 1; -} - diff --git a/api/message/slack-api-message-unimplemented.h b/api/message/slack-api-message-unimplemented.h deleted file mode 100644 index 0e46d70..0000000 --- a/api/message/slack-api-message-unimplemented.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_MESSAGE_UNIMPLEMENTED_H_ -#define _SLACK_API_MESSAGE_UNIMPLEMENTED_H_ - -int slack_api_message_unimplemented( - struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_MESSAGE_UNIMPLEMENTED_H*/ diff --git a/api/slack-api-error.c b/api/slack-api-error.c deleted file mode 100644 index 0ed9b4b..0000000 --- a/api/slack-api-error.c +++ /dev/null @@ -1,63 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-api.h" -#include "slack-api-error.h" - -static const char *type = "error"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %s%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), type, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_error_handle(struct t_slack_workspace *workspace, - int code, const char *msg) -{ - weechat_printf( - workspace->buffer, - _("%s%s: error %d: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - code, msg); - - return 0; -} - -int slack_api_error(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *error, *code, *msg; - - error = json_object_object_get(message, "error"); - if (!json_valid(error, workspace)) - return 0; - - code = json_object_object_get(error, "code"); - if (!json_valid(code, workspace)) - return 0; - - msg = json_object_object_get(error, "msg"); - if (!json_valid(msg, workspace)) - return 0; - - return slack_api_error_handle(workspace, - json_object_get_int(code), - json_object_get_string(msg)); -} diff --git a/api/slack-api-error.h b/api/slack-api-error.h deleted file mode 100644 index d6f52ed..0000000 --- a/api/slack-api-error.h +++ /dev/null @@ -1,11 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_ERROR_H_ -#define _SLACK_API_ERROR_H_ - -int slack_api_error(struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_ERROR_H*/ diff --git a/api/slack-api-hello.c b/api/slack-api-hello.c deleted file mode 100644 index 611cfc6..0000000 --- a/api/slack-api-hello.c +++ /dev/null @@ -1,54 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-api.h" -#include "slack-api-hello.h" -#include "../request/slack-request-channels-list.h" -#include "../request/slack-request-users-list.h" -#include "../request/slack-request-emoji-list.h" - -int slack_api_hello_handle(struct t_slack_workspace *workspace) -{ - struct t_slack_request *request; - - weechat_printf( - workspace->buffer, - _("%s%s: connected!"), - weechat_prefix("network"), SLACK_PLUGIN_NAME); - - request = slack_request_users_list(workspace, - weechat_config_string( - workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]), - ""); - if (request) - slack_workspace_register_request(workspace, request); - - request = slack_request_channels_list(workspace, - weechat_config_string( - workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]), - ""); - if (request) - slack_workspace_register_request(workspace, request); - - request = slack_request_emoji_list(workspace, - weechat_config_string( - workspace->options[SLACK_WORKSPACE_OPTION_TOKEN])); - if (request) - slack_workspace_register_request(workspace, request); - - return 1; -} - -int slack_api_hello(struct t_slack_workspace *workspace, - json_object *message) -{ - (void) message; - - return slack_api_hello_handle(workspace); -} diff --git a/api/slack-api-hello.h b/api/slack-api-hello.h deleted file mode 100644 index f3786d8..0000000 --- a/api/slack-api-hello.h +++ /dev/null @@ -1,11 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_HELLO_H_ -#define _SLACK_API_HELLO_H_ - -int slack_api_hello(struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_HELLO_H*/ diff --git a/api/slack-api-message.c b/api/slack-api-message.c deleted file mode 100644 index f755c19..0000000 --- a/api/slack-api-message.c +++ /dev/null @@ -1,240 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-api.h" -#include "../slack-channel.h" -#include "../slack-user.h" -#include "../slack-message.h" -#include "slack-api-message.h" -#include "message/slack-api-message-unimplemented.h" -#include "message/slack-api-message-bot-message.h" -#include "message/slack-api-message-me-message.h" -#include "message/slack-api-message-slackbot-response.h" - -static const char *type = "message"; - -struct stringcase -{ - const char *string; - int (*func)(struct t_slack_workspace *workspace, - json_object *message); -}; - -static struct stringcase cases[] = -{ { "bot_message", &slack_api_message_bot_message } -, { "channel_archive", &slack_api_message_unimplemented } -, { "channel_join", &slack_api_message_unimplemented } -, { "channel_leave", &slack_api_message_unimplemented } -, { "channel_name", &slack_api_message_unimplemented } -, { "channel_purpose", &slack_api_message_unimplemented } -, { "channel_topic", &slack_api_message_unimplemented } -, { "channel_unarchive", &slack_api_message_unimplemented } -, { "file_comment", &slack_api_message_unimplemented } -, { "file_mention", &slack_api_message_unimplemented } -, { "file_share", &slack_api_message_unimplemented } -, { "group_archive", &slack_api_message_unimplemented } -, { "group_join", &slack_api_message_unimplemented } -, { "group_leave", &slack_api_message_unimplemented } -, { "group_name", &slack_api_message_unimplemented } -, { "group_purpose", &slack_api_message_unimplemented } -, { "group_topic", &slack_api_message_unimplemented } -, { "group_unarchive", &slack_api_message_unimplemented } -, { "me_message", &slack_api_message_me_message } -, { "message_changed", &slack_api_message_unimplemented } -, { "message_deleted", &slack_api_message_unimplemented } -, { "message_replied", &slack_api_message_unimplemented } -, { "pinned_item", &slack_api_message_unimplemented } -, { "reply_broadcast", &slack_api_message_unimplemented } -, { "slackbot_response", &slack_api_message_slackbot_response } -, { "thread_broadcast", &slack_api_message_unimplemented } -, { "unpinned_item", &slack_api_message_unimplemented } -}; - -static int stringcase_cmp(const void *p1, const void *p2) -{ - return strcasecmp(((struct stringcase*)p1)->string, ((struct stringcase*)p2)->string); -} - -void slack_api_message_init() -{ - size_t case_count = sizeof(cases) / sizeof(cases[0]); - qsort(cases, case_count, sizeof(struct stringcase), stringcase_cmp); -} - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %s%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), type, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_message_message_handle(struct t_slack_workspace *workspace, - const char *channel, const char *user, - const char *text, const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - struct t_slack_channel_typing *ptr_typing; - - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; /* silently ignore if channel hasn't been loaded yet */ - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; /* silently ignore if user hasn't been loaded yet */ - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message", - _("%s%s"), - slack_user_as_prefix(workspace, ptr_user, NULL), - message); - slack_channel_member_speaking_add(ptr_channel, ptr_user->profile.display_name, - weechat_string_has_highlight( - message, - ptr_user->profile.display_name)); - free(message); - - ptr_typing = slack_channel_typing_search(ptr_channel, - ptr_user->profile.display_name); - if (ptr_typing) - { - slack_channel_typing_free(ptr_channel, ptr_typing); - slack_channel_typing_cb(ptr_channel, NULL, 0); - } - - return 1; -} - -int slack_api_message_attachment_handle(struct t_slack_workspace *workspace, - const char *channel, const char *user, - const char *text, const char *ts) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; /* silently ignore if channel hasn't been loaded yet */ - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; /* silently ignore if user hasn't been loaded yet */ - - char *message = slack_message_decode(workspace, text); - weechat_printf_date_tags( - ptr_channel->buffer, - (time_t)atof(ts), - "slack_message", - _("%s%s"), - "++\t", - message); - free(message); - - return 1; -} - -int slack_api_message_route_message(struct t_slack_workspace *workspace, - const char *subtype, - json_object *message) -{ - struct stringcase key; - key.string = subtype; - - size_t case_count = sizeof(cases) / sizeof(cases[0]); - void *entry_ptr = bsearch(&key, cases, case_count, - sizeof(struct stringcase), stringcase_cmp); - - if (entry_ptr) - { - struct stringcase *entry = (struct stringcase *)entry_ptr; - return (*entry->func)(workspace, message); - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: got unhandled message of type: message.%s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - subtype); - return 1; - } -} - -int slack_api_message(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *subtype, *channel, *user, *text, *ts; - json_object *attachments, *attachment, *fallback; - int i, rc; - - subtype = json_object_object_get(message, "subtype"); - if (!subtype) - { /* normal message */ - channel = json_object_object_get(message, "channel"); - if (!json_valid(channel, workspace)) - return 0; - - user = json_object_object_get(message, "user"); - if (!json_valid(user, workspace)) - return 0; - - text = json_object_object_get(message, "text"); - if (!json_valid(text, workspace)) - return 0; - - ts = json_object_object_get(message, "ts"); - if (!json_valid(ts, workspace)) - return 0; - - rc = slack_api_message_message_handle(workspace, - json_object_get_string(channel), - json_object_get_string(user), - json_object_get_string(text), - json_object_get_string(ts)); - attachments = json_object_object_get(message, "attachments"); - if (json_valid(attachments, workspace)) - { - for (i = json_object_array_length(attachments); i > 0; i--) - { - attachment = json_object_array_get_idx(attachments, i - 1); - if (!json_valid(attachment, workspace)) - continue; - - fallback = json_object_object_get(attachment, "fallback"); - if (!json_valid(fallback, workspace)) - continue; - - slack_api_message_attachment_handle(workspace, - json_object_get_string(channel), - json_object_get_string(user), - json_object_get_string(fallback), - json_object_get_string(ts)); - } - } - return rc; - } - else - { /* special message */ - return slack_api_message_route_message(workspace, - json_object_get_string(subtype), - message); - } -} diff --git a/api/slack-api-message.h b/api/slack-api-message.h deleted file mode 100644 index b72ffa4..0000000 --- a/api/slack-api-message.h +++ /dev/null @@ -1,13 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_MESSAGE_H_ -#define _SLACK_API_MESSAGE_H_ - -int slack_api_message(struct t_slack_workspace *workspace, - json_object *message); - -void slack_api_message_init(); - -#endif /*SLACK_API_MESSAGE_H*/ diff --git a/api/slack-api-user-typing.c b/api/slack-api-user-typing.c deleted file mode 100644 index 1909dbd..0000000 --- a/api/slack-api-user-typing.c +++ /dev/null @@ -1,67 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-user.h" -#include "../slack-channel.h" -#include "../slack-api.h" -#include "slack-api-user-typing.h" - -static const char *type = "user_typing"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error handling websocket %s%s%s message: " - "unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - weechat_color("chat_value"), type, weechat_color("reset")); - return 0; - } - - return 1; -} - -int slack_api_user_typing_handle(struct t_slack_workspace *workspace, - const char *channel, const char *user) -{ - struct t_slack_channel *ptr_channel; - struct t_slack_user *ptr_user; - - ptr_channel = slack_channel_search(workspace, channel); - if (!ptr_channel) - return 1; /* silently ignore if channel hasn't been loaded yet */ - ptr_user = slack_user_search(workspace, user); - if (!ptr_user) - return 1; /* silently ignore if user hasn't been loaded yet */ - - slack_channel_add_typing(ptr_channel, ptr_user); - - return 1; -} - -int slack_api_user_typing(struct t_slack_workspace *workspace, - json_object *message) -{ - json_object *channel, *user; - - channel = json_object_object_get(message, "channel"); - if (!json_valid(channel, workspace)) - return 0; - - user = json_object_object_get(message, "user"); - if (!json_valid(user, workspace)) - return 0; - - return slack_api_user_typing_handle(workspace, - json_object_get_string(channel), - json_object_get_string(user)); -} diff --git a/api/slack-api-user-typing.h b/api/slack-api-user-typing.h deleted file mode 100644 index c036333..0000000 --- a/api/slack-api-user-typing.h +++ /dev/null @@ -1,11 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_API_USER_TYPING_H_ -#define _SLACK_API_USER_TYPING_H_ - -int slack_api_user_typing(struct t_slack_workspace *workspace, - json_object *message); - -#endif /*SLACK_API_USER_TYPING_H*/ diff --git a/xmpp-command.c b/command.c similarity index 99% rename from xmpp-command.c rename to command.c index 44ae73c..ff62b1a 100644 --- a/xmpp-command.c +++ b/command.c @@ -7,14 +7,14 @@ #include #include -#include "xmpp.h" +#include "plugin.h" //#include "xmpp-oauth.h" //#include "xmpp-teaminfo.h" //#include "xmpp-workspace.h" //#include "xmpp-channel.h" //#include "xmpp-buffer.h" //#include "xmpp-message.h" -#include "xmpp-command.h" +#include "command.h" //#include "request/xmpp-request-chat-memessage.h" /* diff --git a/xmpp-command.h b/command.h similarity index 70% rename from xmpp-command.h rename to command.h index 62be0e5..1e79a41 100644 --- a/xmpp-command.h +++ b/command.h @@ -2,9 +2,9 @@ // License, version 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _XMPP_COMMAND_H_ -#define _XMPP_COMMAND_H_ +#ifndef _WEECHAT_XMPP_COMMAND_H_ +#define _WEECHAT_XMPP_COMMAND_H_ extern void xmpp_command_init(); -#endif /*XMPP_COMMAND_H*/ +#endif /*WEECHAT_XMPP_COMMAND_H*/ diff --git a/xmpp-config.c b/config.c similarity index 99% rename from xmpp-config.c rename to config.c index 2169e49..cc5789b 100644 --- a/xmpp-config.c +++ b/config.c @@ -7,8 +7,8 @@ #include #include -#include "xmpp.h" -#include "xmpp-config.h" +#include "plugin.h" +#include "config.h" struct t_config_file *xmpp_config_file; @@ -241,7 +241,7 @@ int xmpp_config_init() struct t_config_section *ptr_section_server; struct t_config_section *ptr_section_look; - xmpp_config_file = weechat_config_new(XMPP_CONFIG_NAME, + xmpp_config_file = weechat_config_new(WEECHAT_XMPP_CONFIG_NAME, &xmpp_config_reload, NULL, NULL); if(!xmpp_config_file) diff --git a/xmpp-config.h b/config.h similarity index 95% rename from xmpp-config.h rename to config.h index 128d8a4..c291cc4 100644 --- a/xmpp-config.h +++ b/config.h @@ -2,10 +2,10 @@ // License, version 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _XMPP_CONFIG_H_ -#define _XMPP_CONFIG_H_ +#ifndef _WEECHAT_XMPP_CONFIG_H_ +#define _WEECHAT_XMPP_CONFIG_H_ -#define XMPP_CONFIG_NAME "xmpp" +#define WEECHAT_XMPP_CONFIG_NAME "xmpp" enum t_xmpp_config_nick_completion { @@ -56,4 +56,4 @@ extern int xmpp_config_read(); extern int xmpp_config_write(); extern void xmpp_config_free(); -#endif /*XMPP_CONFIG_H*/ +#endif /*WEECHAT_XMPP_CONFIG_H*/ diff --git a/xmpp-connection.c b/connection.c similarity index 98% rename from xmpp-connection.c rename to connection.c index 1fdc6d6..6ac95a2 100644 --- a/xmpp-connection.c +++ b/connection.c @@ -8,9 +8,9 @@ #include #include -#include "xmpp.h" -#include "xmpp-config.h" -#include "xmpp-connection.h" +#include "plugin.h" +#include "config.h" +#include "connection.h" //#include "api/xmpp-api-hello.h" //#include "api/xmpp-api-error.h" //#include "api/xmpp-api-message.h" @@ -30,7 +30,7 @@ void xmpp_log_emit_weechat(void *const userdata, const xmpp_log_level_t level, c weechat_printf( NULL, _("%s%s/%s (%s): %s"), - weechat_prefix("error"), XMPP_PLUGIN_NAME, area, + weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME, area, log_level_name[level], msg); } diff --git a/xmpp-connection.h b/connection.h similarity index 85% rename from xmpp-connection.h rename to connection.h index 9d323fb..d2f3448 100644 --- a/xmpp-connection.h +++ b/connection.h @@ -2,8 +2,8 @@ // License, version 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _XMPP_CONNECTION_H_ -#define _XMPP_CONNECTION_H_ +#ifndef _WEECHAT_XMPP_CONNECTION_H_ +#define _WEECHAT_XMPP_CONNECTION_H_ extern xmpp_conn_t *xmpp_connection; @@ -18,4 +18,4 @@ int xmpp_connection_check_events(const void *pointer, void *data, int remaining_ int xmpp_connection_route_message(xmpp_conn_t *connection, const char *type, json_object *message); -#endif /*XMPP_CONNECTION_H*/ +#endif /*WEECHAT_XMPP_CONNECTION_H*/ diff --git a/xmpp.c b/plugin.c similarity index 93% rename from xmpp.c rename to plugin.c index 6138be1..1381694 100644 --- a/xmpp.c +++ b/plugin.c @@ -9,19 +9,19 @@ #include #include -#include "xmpp.h" -#include "xmpp-config.h" -#include "xmpp-connection.h" -#include "xmpp-command.h" +#include "plugin.h" +#include "config.h" +#include "connection.h" +#include "command.h" //#include "xmpp-workspace.h" //#include "xmpp-buffer.h" //#include "xmpp-completion.h" -WEECHAT_PLUGIN_NAME(XMPP_PLUGIN_NAME); +WEECHAT_PLUGIN_NAME(WEECHAT_XMPP_PLUGIN_NAME); WEECHAT_PLUGIN_DESCRIPTION(N_("XMPP protocol")); WEECHAT_PLUGIN_AUTHOR("bqv "); -WEECHAT_PLUGIN_VERSION(XMPP_PLUGIN_VERSION); +WEECHAT_PLUGIN_VERSION(WEECHAT_XMPP_PLUGIN_VERSION); WEECHAT_PLUGIN_LICENSE("MPL2"); WEECHAT_PLUGIN_PRIORITY(5500); diff --git a/xmpp.h b/plugin.h similarity index 66% rename from xmpp.h rename to plugin.h index a70ebae..bc5ff5d 100644 --- a/xmpp.h +++ b/plugin.h @@ -2,13 +2,13 @@ // License, version 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _XMPP_H_ -#define _XMPP_H_ +#ifndef _WEECHAT_XMPP_H_ +#define _WEECHAT_XMPP_H_ #define weechat_plugin weechat_xmpp_plugin -#define XMPP_PLUGIN_NAME "xmpp" -#define XMPP_PLUGIN_VERSION "0.1" +#define WEECHAT_XMPP_PLUGIN_NAME "xmpp" +#define WEECHAT_XMPP_PLUGIN_VERSION "0.1" extern struct t_weechat_plugin *weechat_xmpp_plugin; -#endif /*XMPP_H*/ +#endif /*WEECHAT_XMPP_H*/ diff --git a/request/slack-request-bots-info.c b/request/slack-request-bots-info.c deleted file mode 100644 index 278d467..0000000 --- a/request/slack-request-bots-info.c +++ /dev/null @@ -1,272 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-channel.h" -#include "../slack-request.h" -#include "../slack-user.h" -#include "../request/slack-request-bots-info.h" - -static const char *const endpoint = "/api/bots.info?" - "token=%s&bot=%s"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error retrieving bot info: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - //__asm__("int3"); - return 0; - } - - return 1; -} - -static const struct lws_protocols protocols[]; - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_request *request = (struct t_slack_request *)user; - struct lws_client_connect_info ccinfo; - - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - in ? (char *)in : "(null)"); - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) reconnecting..."), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) retrieving bot info... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (request->json_chunks) - { - for (last_chunk = request->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - request->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - char cursor[64]; - json_object *response, *ok, *error, *members, *metadata; - json_object *user, *id, *name, *profile, *display_name, *next_cursor; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (request->json_chunks) - { - chunk_count++; - for (chunk_ptr = request->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = request->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(request->json_chunks->data); - free(request->json_chunks); - request->json_chunks = chunk_ptr; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - // TODO: this - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) failed to retrieve users: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - request->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_request *slack_request_bots_info( - struct t_slack_workspace *workspace, - const char *token, const char *cursor) -{ - struct t_slack_request *request; - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - - request = slack_request_alloc(workspace); - - size_t urilen = snprintf(NULL, 0, endpoint, token, cursor) + 1; - request->uri = malloc(urilen); - snprintf(request->uri, urilen, endpoint, token, cursor); - - memset(&ctxinfo, 0, sizeof(ctxinfo)); /* otherwise uninitialized garbage */ - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - ctxinfo.protocols = protocols; - - request->context = lws_create_context(&ctxinfo); - if (!request->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - return NULL; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx); - } - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - - return request; -} diff --git a/request/slack-request-bots-info.h b/request/slack-request-bots-info.h deleted file mode 100644 index f743f13..0000000 --- a/request/slack-request-bots-info.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_BOTS_INFO_H_ -#define _SLACK_REQUEST_BOTS_INFO_H_ - -struct t_slack_request *slack_request_bots_info( - struct t_slack_workspace *workspace, - const char *token, const char *cursor); - -#endif /*SLACK_REQUEST_BOTS_INFO_H*/ diff --git a/request/slack-request-channels-list.c b/request/slack-request-channels-list.c deleted file mode 100644 index 6e2d30e..0000000 --- a/request/slack-request-channels-list.c +++ /dev/null @@ -1,431 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-request.h" -#include "../slack-channel.h" -#include "../request/slack-request-channels-list.h" - -static const char *const endpoint = "/api/channels.list?" - "token=%s&cursor=%s&" - "exclude_archived=false&exclude_members=true&limit=20"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error retrieving channels: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - //__asm__("int3"); - return 0; - } - - return 1; -} - -static const struct lws_protocols protocols[]; - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_request *request = (struct t_slack_request *)user; - struct lws_client_connect_info ccinfo; - - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - in ? (char *)in : "(null)"); - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) reconnecting..."), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) retrieving channels... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (request->json_chunks) - { - for (last_chunk = request->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - request->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - char cursor[64]; - json_object *response, *ok, *error, *channels, *metadata; - json_object *channel, *id, *name, *created; - json_object *is_general, *name_normalized, *is_shared, *is_org_shared, *is_member; - json_object *topic, *purpose, *is_archived; - json_object *sub_value, *sub_creator, *sub_last_set; - json_object *creator, *next_cursor; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (request->json_chunks) - { - chunk_count++; - for (chunk_ptr = request->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = request->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(request->json_chunks->data); - free(request->json_chunks); - request->json_chunks = chunk_ptr; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - channels = json_object_object_get(response, "channels"); - if (!json_valid(channels, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - for (i = json_object_array_length(channels); i > 0; i--) - { - struct t_slack_channel *new_channel; - - channel = json_object_array_get_idx(channels, i - 1); - if (!json_valid(channel, request->workspace)) - { - continue; - } - - id = json_object_object_get(channel, "id"); - if (!json_valid(id, request->workspace)) - { - continue; - } - - name = json_object_object_get(channel, "name"); - if (!json_valid(name, request->workspace)) - { - continue; - } - - new_channel = slack_channel_new( - request->workspace, - SLACK_CHANNEL_TYPE_CHANNEL, - json_object_get_string(id), - json_object_get_string(name)); - - created = json_object_object_get(channel, "created"); - if (json_valid(created, request->workspace)) - { - new_channel->created = json_object_get_int(created); - } - - is_general = json_object_object_get(channel, "is_general"); - if (json_valid(is_general, request->workspace)) - { - new_channel->is_general = json_object_get_boolean(is_general); - } - - name_normalized = json_object_object_get(channel, "name_normalized"); - if (json_valid(name_normalized, request->workspace)) - { - new_channel->name_normalized = strdup( - json_object_get_string(name_normalized)); - } - - is_shared = json_object_object_get(channel, "is_shared"); - if (json_valid(is_shared, request->workspace)) - { - new_channel->is_shared = json_object_get_boolean(is_shared); - } - - is_org_shared = json_object_object_get(channel, "is_org_shared"); - if (json_valid(is_org_shared, request->workspace)) - { - new_channel->is_org_shared = json_object_get_boolean(is_org_shared); - } - - is_member = json_object_object_get(channel, "is_member"); - if (json_valid(is_member, request->workspace)) - { - new_channel->is_member = json_object_get_boolean(is_member); - } - - topic = json_object_object_get(channel, "topic"); - if (json_valid(topic, request->workspace)) - { - sub_value = json_object_object_get(topic, "value"); - - sub_creator = json_object_object_get(topic, "creator"); - - sub_last_set = json_object_object_get(topic, "last_set"); - - slack_channel_update_topic(new_channel, - json_valid(sub_value, request->workspace) ? - json_object_get_string(sub_value) : - NULL, - json_valid(sub_creator, request->workspace) ? - json_object_get_string(sub_creator) : - NULL, - json_valid(sub_last_set, request->workspace) ? - json_object_get_int(sub_last_set) : - 0); - } - - purpose = json_object_object_get(channel, "purpose"); - if (json_valid(purpose, request->workspace)) - { - sub_value = json_object_object_get(topic, "value"); - - sub_creator = json_object_object_get(topic, "creator"); - - sub_last_set = json_object_object_get(topic, "last_set"); - - slack_channel_update_purpose(new_channel, - json_valid(sub_value, request->workspace) ? - json_object_get_string(sub_value) : - NULL, - json_valid(sub_creator, request->workspace) ? - json_object_get_string(sub_creator) : - NULL, - json_valid(sub_last_set, request->workspace) ? - json_object_get_int(sub_last_set) : - 0); - } - - is_archived = json_object_object_get(response, "is_archived"); - if (json_valid(is_archived, request->workspace)) - { - new_channel->is_archived = json_object_get_boolean(is_archived); - } - - creator = json_object_object_get(response, "creator"); - if (json_valid(creator, request->workspace)) - { - new_channel->creator = strdup(json_object_get_string(creator)); - } - } - - metadata = json_object_object_get(response, "response_metadata"); - if (!json_valid(metadata, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - next_cursor = json_object_object_get(metadata, "next_cursor"); - if (!json_valid(next_cursor, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - lws_urlencode(cursor, json_object_get_string(next_cursor), sizeof(cursor)); - - if (cursor[0]) - { - struct t_slack_request *next_request; - - next_request = slack_request_channels_list(request->workspace, - weechat_config_string( - request->workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]), - cursor); - if (next_request) - slack_workspace_register_request(request->workspace, next_request); - } - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) failed to retrieve channels: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - request->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_request *slack_request_channels_list( - struct t_slack_workspace *workspace, - const char *token, const char *cursor) -{ - struct t_slack_request *request; - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - - request = slack_request_alloc(workspace); - - size_t urilen = snprintf(NULL, 0, endpoint, token, cursor) + 1; - request->uri = malloc(urilen); - snprintf(request->uri, urilen, endpoint, token, cursor); - - memset(&ctxinfo, 0, sizeof(ctxinfo)); /* otherwise uninitialized garbage */ - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - ctxinfo.protocols = protocols; - - request->context = lws_create_context(&ctxinfo); - if (!request->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - return NULL; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx); - } - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - - return request; -} diff --git a/request/slack-request-channels-list.h b/request/slack-request-channels-list.h deleted file mode 100644 index d965538..0000000 --- a/request/slack-request-channels-list.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_CHANNELS_LIST_H_ -#define _SLACK_REQUEST_CHANNELS_LIST_H_ - -struct t_slack_request *slack_request_channels_list( - struct t_slack_workspace *workspace, - const char *token, const char *cursor); - -#endif /*SLACK_REQUEST_CHANNELS_LIST_H*/ diff --git a/request/slack-request-chat-memessage.c b/request/slack-request-chat-memessage.c deleted file mode 100644 index 38a0487..0000000 --- a/request/slack-request-chat-memessage.c +++ /dev/null @@ -1,270 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-request.h" -#include "../slack-user.h" -#include "../request/slack-request-chat-memessage.h" - -static const char *const endpoint = "/api/chat.meMessage?" - "token=%s&channel=%s&text=%s&"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error sending me-message: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - //__asm__("int3"); - return 0; - } - - return 1; -} - -static const struct lws_protocols protocols[]; - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_request *request = (struct t_slack_request *)user; - struct lws_client_connect_info ccinfo; - - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - in ? (char *)in : "(null)"); - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) reconnecting..."), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) sending me-message... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (request->json_chunks) - { - for (last_chunk = request->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - request->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - json_object *response, *ok, *error; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (request->json_chunks) - { - chunk_count++; - for (chunk_ptr = request->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = request->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(request->json_chunks->data); - free(request->json_chunks); - request->json_chunks = chunk_ptr; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - /* wait for websocket to catch up */ - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) failed to send me-message: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - request->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_request *slack_request_chat_memessage( - struct t_slack_workspace *workspace, - const char *token, const char *channel, - const char *text) -{ - struct t_slack_request *request; - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - - request = slack_request_alloc(workspace); - - size_t urilen = snprintf(NULL, 0, endpoint, token, channel, text) + 1; - request->uri = malloc(urilen); - snprintf(request->uri, urilen, endpoint, token, channel, text); - - memset(&ctxinfo, 0, sizeof(ctxinfo)); /* otherwise uninitialized garbage */ - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - ctxinfo.protocols = protocols; - - request->context = lws_create_context(&ctxinfo); - if (!request->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - return NULL; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx); - } - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - - return request; -} diff --git a/request/slack-request-chat-memessage.h b/request/slack-request-chat-memessage.h deleted file mode 100644 index d93c95b..0000000 --- a/request/slack-request-chat-memessage.h +++ /dev/null @@ -1,13 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_CHAT_MEMESSAGE_H_ -#define _SLACK_REQUEST_CHAT_MEMESSAGE_H_ - -struct t_slack_request *slack_request_chat_memessage( - struct t_slack_workspace *workspace, - const char *token, const char *channel, - const char *text); - -#endif /*SLACK_REQUEST_CHAT_MEMESSAGE_H*/ diff --git a/request/slack-request-chat-postmessage.c b/request/slack-request-chat-postmessage.c deleted file mode 100644 index 1bf644c..0000000 --- a/request/slack-request-chat-postmessage.c +++ /dev/null @@ -1,271 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-request.h" -#include "../slack-user.h" -#include "../request/slack-request-chat-postmessage.h" - -static const char *const endpoint = "/api/chat.postMessage?" - "token=%s&channel=%s&text=%s&" - "as_user=true&link_names=true&mrkdwn=false&parse=full"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error posting message: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - //__asm__("int3"); - return 0; - } - - return 1; -} - -static const struct lws_protocols protocols[]; - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_request *request = (struct t_slack_request *)user; - struct lws_client_connect_info ccinfo; - - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - in ? (char *)in : "(null)"); - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) reconnecting..."), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) posting message... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (request->json_chunks) - { - for (last_chunk = request->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - request->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - json_object *response, *ok, *error; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (request->json_chunks) - { - chunk_count++; - for (chunk_ptr = request->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = request->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(request->json_chunks->data); - free(request->json_chunks); - request->json_chunks = chunk_ptr; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - /* wait for websocket to catch up */ - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) failed to post message: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - request->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_request *slack_request_chat_postmessage( - struct t_slack_workspace *workspace, - const char *token, const char *channel, - const char *text) -{ - struct t_slack_request *request; - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - - request = slack_request_alloc(workspace); - - size_t urilen = snprintf(NULL, 0, endpoint, token, channel, text) + 1; - request->uri = malloc(urilen); - snprintf(request->uri, urilen, endpoint, token, channel, text); - - memset(&ctxinfo, 0, sizeof(ctxinfo)); /* otherwise uninitialized garbage */ - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - ctxinfo.protocols = protocols; - - request->context = lws_create_context(&ctxinfo); - if (!request->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - return NULL; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx); - } - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - - return request; -} diff --git a/request/slack-request-chat-postmessage.h b/request/slack-request-chat-postmessage.h deleted file mode 100644 index 55be2a3..0000000 --- a/request/slack-request-chat-postmessage.h +++ /dev/null @@ -1,13 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_CHAT_POSTMESSAGE_H_ -#define _SLACK_REQUEST_CHAT_POSTMESSAGE_H_ - -struct t_slack_request *slack_request_chat_postmessage( - struct t_slack_workspace *workspace, - const char *token, const char *channel, - const char *text); - -#endif /*SLACK_REQUEST_CHAT_POSTMESSAGE_H*/ diff --git a/request/slack-request-conversations-members.c b/request/slack-request-conversations-members.c deleted file mode 100644 index 1b9bd5f..0000000 --- a/request/slack-request-conversations-members.c +++ /dev/null @@ -1,330 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-channel.h" -#include "../slack-request.h" -#include "../slack-user.h" -#include "../request/slack-request-conversations-members.h" - -static const char *const endpoint = "/api/conversations.members?" - "token=%s&channel=%s&cursor=%s&limit=100"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error retrieving members: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - //__asm__("int3"); - return 0; - } - - return 1; -} - -static const struct lws_protocols protocols[]; - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_request *request = (struct t_slack_request *)user; - struct lws_client_connect_info ccinfo; - struct t_slack_channel *channel; - const char *channelid; - - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - in ? (char *)in : "(null)"); - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) reconnecting..."), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) retrieving members... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (request->json_chunks) - { - for (last_chunk = request->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - request->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - char cursor[64]; - json_object *response, *ok, *error, *members; - json_object *user, *metadata, *next_cursor; - struct t_json_chunk *chunk_ptr; - - channelid = (const char *)request->pointer; - channel = slack_channel_search(request->workspace, channelid); - - chunk_count = 0; - if (request->json_chunks) - { - chunk_count++; - for (chunk_ptr = request->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = request->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(request->json_chunks->data); - free(request->json_chunks); - request->json_chunks = chunk_ptr; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - members = json_object_object_get(response, "members"); - if (!json_valid(members, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - for (i = json_object_array_length(members); i > 0; i--) - { - user = json_object_array_get_idx(members, i - 1); - if (!json_valid(user, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - slack_channel_add_member(request->workspace, - channel, - json_object_get_string(user)); - } - - metadata = json_object_object_get(response, "response_metadata"); - if (!json_valid(metadata, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - next_cursor = json_object_object_get(metadata, "next_cursor"); - if (!json_valid(next_cursor, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - lws_urlencode(cursor, json_object_get_string(next_cursor), sizeof(cursor)); - - if (cursor[0]) - { - struct t_slack_request *next_request; - - next_request = slack_request_conversations_members(request->workspace, - weechat_config_string( - request->workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]), - channelid, - cursor); - if (next_request) - slack_workspace_register_request(request->workspace, next_request); - } - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) failed to retrieve users: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - request->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_request *slack_request_conversations_members( - struct t_slack_workspace *workspace, - const char *token, const char *channel, - const char *cursor) -{ - struct t_slack_request *request; - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - - request = slack_request_alloc(workspace); - request->pointer = channel; - - size_t urilen = snprintf(NULL, 0, endpoint, token, channel, cursor) + 1; - request->uri = malloc(urilen); - snprintf(request->uri, urilen, endpoint, token, channel, cursor); - - memset(&ctxinfo, 0, sizeof(ctxinfo)); /* otherwise uninitialized garbage */ - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - ctxinfo.protocols = protocols; - - request->context = lws_create_context(&ctxinfo); - if (!request->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - return NULL; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx); - } - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - - return request; -} diff --git a/request/slack-request-conversations-members.h b/request/slack-request-conversations-members.h deleted file mode 100644 index d5a1458..0000000 --- a/request/slack-request-conversations-members.h +++ /dev/null @@ -1,13 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_CONVERSATIONS_MEMBERS_H_ -#define _SLACK_REQUEST_CONVERSATIONS_MEMBERS_H_ - -struct t_slack_request *slack_request_conversations_members( - struct t_slack_workspace *workspace, - const char *token, const char *channel, - const char *cursor); - -#endif /*SLACK_REQUEST_CONVERSATIONS_MEMBERS_H*/ diff --git a/request/slack-request-emoji-list.c b/request/slack-request-emoji-list.c deleted file mode 100644 index abc303b..0000000 --- a/request/slack-request-emoji-list.c +++ /dev/null @@ -1,287 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-request.h" -#include "../slack-channel.h" -#include "../request/slack-request-emoji-list.h" - -static const char *const endpoint = "/api/emoji.list?" - "token=%s"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error retrieving emoji: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - //__asm__("int3"); - return 0; - } - - return 1; -} - -static const struct lws_protocols protocols[]; - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_request *request = (struct t_slack_request *)user; - struct lws_client_connect_info ccinfo; - - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - in ? (char *)in : "(null)"); - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) reconnecting..."), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) retrieving emoji... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (request->json_chunks) - { - for (last_chunk = request->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - request->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - json_object *response, *ok, *error, *emoji; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (request->json_chunks) - { - chunk_count++; - for (chunk_ptr = request->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = request->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(request->json_chunks->data); - free(request->json_chunks); - request->json_chunks = chunk_ptr; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - emoji = json_object_object_get(response, "emoji"); - if (!json_valid(emoji, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - json_object_object_foreach(emoji, key, val) - { - if (!json_valid(val, request->workspace)) - { - continue; - } - - slack_workspace_add_emoji( - request->workspace, - key, json_object_get_string(val)); - } - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) failed to retrieve emoji: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - request->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_request *slack_request_emoji_list( - struct t_slack_workspace *workspace, - const char *token) -{ - struct t_slack_request *request; - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - - request = slack_request_alloc(workspace); - - size_t urilen = snprintf(NULL, 0, endpoint, token) + 1; - request->uri = malloc(urilen); - snprintf(request->uri, urilen, endpoint, token); - - memset(&ctxinfo, 0, sizeof(ctxinfo)); /* otherwise uninitialized garbage */ - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - ctxinfo.protocols = protocols; - - request->context = lws_create_context(&ctxinfo); - if (!request->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - return NULL; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx); - } - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - - return request; -} diff --git a/request/slack-request-emoji-list.h b/request/slack-request-emoji-list.h deleted file mode 100644 index 19101d1..0000000 --- a/request/slack-request-emoji-list.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_EMOJI_LIST_H_ -#define _SLACK_REQUEST_EMOJI_LIST_H_ - -struct t_slack_request *slack_request_emoji_list( - struct t_slack_workspace *workspace, - const char *token); - -#endif /*SLACK_REQUEST_EMOJI_LIST_H*/ diff --git a/request/slack-request-users-list.c b/request/slack-request-users-list.c deleted file mode 100644 index 33e2dab..0000000 --- a/request/slack-request-users-list.c +++ /dev/null @@ -1,375 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-channel.h" -#include "../slack-request.h" -#include "../slack-user.h" -#include "../request/slack-request-conversations-members.h" -#include "../request/slack-request-users-list.h" - -static const char *const endpoint = "/api/users.list?" - "token=%s&cursor=%s&" - "exclude_archived=false&exclude_members=true&limit=20"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error retrieving users: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - //__asm__("int3"); - return 0; - } - - return 1; -} - -static const struct lws_protocols protocols[]; - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_request *request = (struct t_slack_request *)user; - struct lws_client_connect_info ccinfo; - - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - in ? (char *)in : "(null)"); - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) reconnecting..."), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) retrieving users... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (request->json_chunks) - { - for (last_chunk = request->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - request->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - char cursor[64]; - json_object *response, *ok, *error, *members; - json_object *user, *id, *name; - json_object *profile, *display_name, *bot_id; - json_object *metadata, *next_cursor; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (request->json_chunks) - { - chunk_count++; - for (chunk_ptr = request->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = request->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(request->json_chunks->data); - free(request->json_chunks); - request->json_chunks = chunk_ptr; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - members = json_object_object_get(response, "members"); - if (!json_valid(members, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - for (i = json_object_array_length(members); i > 0; i--) - { - struct t_slack_user *new_user; - - user = json_object_array_get_idx(members, i - 1); - if (!json_valid(user, request->workspace)) - { - continue; - } - - id = json_object_object_get(user, "id"); - if (!json_valid(id, request->workspace)) - { - continue; - } - - name = json_object_object_get(user, "name"); - if (!json_valid(name, request->workspace)) - { - continue; - } - - profile = json_object_object_get(user, "profile"); - if (!json_valid(profile, request->workspace)) - { - continue; - } - - display_name = json_object_object_get(profile, "display_name"); - if (!json_valid(display_name, request->workspace)) - { - continue; - } - - new_user = slack_user_new(request->workspace, - json_object_get_string(id), - json_object_get_string(display_name)[0] ? - json_object_get_string(display_name) : - json_object_get_string(name)); - - bot_id = json_object_object_get(profile, "bot_id"); - if (json_valid(bot_id, request->workspace)) - { - new_user->profile.bot_id = strdup(json_object_get_string(bot_id)); - } - } - - metadata = json_object_object_get(response, "response_metadata"); - if (!json_valid(metadata, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - next_cursor = json_object_object_get(metadata, "next_cursor"); - if (!json_valid(next_cursor, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - lws_urlencode(cursor, json_object_get_string(next_cursor), sizeof(cursor)); - - if (cursor[0]) - { - struct t_slack_request *next_request; - - next_request = slack_request_users_list(request->workspace, - weechat_config_string( - request->workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]), - cursor); - if (next_request) - slack_workspace_register_request(request->workspace, next_request); - } - else - { - struct t_slack_request *next_request; - struct t_slack_channel *ptr_channel; - - for (ptr_channel = request->workspace->channels; ptr_channel; - ptr_channel = ptr_channel->next_channel) - { - next_request = slack_request_conversations_members(request->workspace, - weechat_config_string( - request->workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]), - ptr_channel->id, - cursor); - if (next_request) - slack_workspace_register_request(request->workspace, next_request); - } - } - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, request->workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - request->workspace->buffer, - _("%s%s: (%d) failed to retrieve users: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - request->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_request *slack_request_users_list( - struct t_slack_workspace *workspace, - const char *token, const char *cursor) -{ - struct t_slack_request *request; - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - - request = slack_request_alloc(workspace); - - size_t urilen = snprintf(NULL, 0, endpoint, token, cursor) + 1; - request->uri = malloc(urilen); - snprintf(request->uri, urilen, endpoint, token, cursor); - - memset(&ctxinfo, 0, sizeof(ctxinfo)); /* otherwise uninitialized garbage */ - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - ctxinfo.protocols = protocols; - - request->context = lws_create_context(&ctxinfo); - if (!request->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, request->idx); - return NULL; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: (%d) contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, request->idx); - } - - memset(&ccinfo, 0, sizeof(ccinfo)); /* otherwise uninitialized garbage */ - ccinfo.context = request->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.port = 443; - ccinfo.address = "slack.com"; - ccinfo.path = request->uri; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.method = "GET"; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &request->client_wsi; - ccinfo.userdata = request; - - lws_client_connect_via_info(&ccinfo); - - return request; -} diff --git a/request/slack-request-users-list.h b/request/slack-request-users-list.h deleted file mode 100644 index e5e3825..0000000 --- a/request/slack-request-users-list.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_USERS_LIST_H_ -#define _SLACK_REQUEST_USERS_LIST_H_ - -struct t_slack_request *slack_request_users_list( - struct t_slack_workspace *workspace, - const char *token, const char *cursor); - -#endif /*SLACK_REQUEST_USERS_LIST_H*/ diff --git a/slack-buffer.c b/slack-buffer.c deleted file mode 100644 index c922cfc..0000000 --- a/slack-buffer.c +++ /dev/null @@ -1,164 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-workspace.h" -#include "slack-channel.h" -#include "slack-buffer.h" - -void slack_buffer_get_workspace_and_channel(struct t_gui_buffer *buffer, - struct t_slack_workspace **workspace, - struct t_slack_channel **channel) -{ - struct t_slack_workspace *ptr_workspace; - struct t_slack_channel *ptr_channel; - - if (!buffer) - return; - - /* look for a workspace or channel using this buffer */ - for (ptr_workspace = slack_workspaces; ptr_workspace; - ptr_workspace = ptr_workspace->next_workspace) - { - if (ptr_workspace->buffer == buffer) - { - if (workspace) - *workspace = ptr_workspace; - return; - } - - for (ptr_channel = ptr_workspace->channels; ptr_channel; - ptr_channel = ptr_channel->next_channel) - { - if (ptr_channel->buffer == buffer) - { - if (workspace) - *workspace = ptr_workspace; - if (channel) - *channel = ptr_channel; - return; - } - } - } - - /* no workspace or channel found */ -} - -char *slack_buffer_typing_bar_cb(const void *pointer, - void *data, - struct t_gui_bar_item *item, - struct t_gui_window *window, - struct t_gui_buffer *buffer, - struct t_hashtable *extra_info) -{ - struct t_slack_channel_typing *ptr_typing; - struct t_slack_workspace *workspace; - struct t_slack_channel *channel; - char notification[256]; - unsigned typecount; - - (void) pointer; - (void) data; - (void) item; - (void) window; - (void) extra_info; - - workspace = NULL; - channel = NULL; - - slack_buffer_get_workspace_and_channel(buffer, &workspace, &channel); - - if (!channel) - return strdup(""); - - typecount = 0; - - for (ptr_typing = channel->typings; ptr_typing; - ptr_typing = ptr_typing->next_typing) - { - switch (++typecount) - { - case 1: - strcpy(notification, ptr_typing->name); - break; - case 2: - strcat(notification, ", "); - strcat(notification, ptr_typing->name); - break; - case 3: - default: - strcpy(notification, "Several people"); - break; - } - } - - if (typecount) - { - strcat(notification, NG_(" is typing...", - " are typing...", - typecount)); - return strdup(notification); - } - else - { - return strdup(""); - } -} - -int slack_buffer_nickcmp_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *nick1, - const char *nick2) -{ - struct t_slack_workspace *workspace; - - (void) data; - - if (pointer) - workspace = (struct t_slack_workspace *)pointer; - else - slack_buffer_get_workspace_and_channel(buffer, &workspace, NULL); - - if (workspace) - { - return weechat_strcasecmp(nick1, nick2); - } - else - { - return weechat_strcasecmp(nick1, nick2); - } -} - -int slack_buffer_close_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer) -{ - struct t_weechat_plugin *buffer_plugin = NULL; - struct t_slack_workspace *ptr_workspace = NULL; - struct t_slack_channel *ptr_channel = NULL; - - buffer_plugin = weechat_buffer_get_pointer(buffer, "plugin"); - if (buffer_plugin == weechat_slack_plugin) - slack_buffer_get_workspace_and_channel(buffer, - &ptr_workspace, &ptr_channel); - - (void) pointer; - (void) data; - (void) buffer; - - if (ptr_workspace) - { - if (!ptr_workspace->disconnected) - { - //slack_command_quit_workspace(ptr_workspace, NULL); - slack_workspace_disconnect(ptr_workspace, 0); - } - - ptr_workspace->buffer = NULL; - } - - return WEECHAT_RC_OK; -} diff --git a/slack-buffer.h b/slack-buffer.h deleted file mode 100644 index 3f4bc66..0000000 --- a/slack-buffer.h +++ /dev/null @@ -1,27 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_BUFFER_H_ -#define _SLACK_BUFFER_H_ - -void slack_buffer_get_workspace_and_channel(struct t_gui_buffer *buffer, - struct t_slack_workspace **workspace, - struct t_slack_channel **channel); - -char *slack_buffer_typing_bar_cb(const void *pointer, - void *data, - struct t_gui_bar_item *item, - struct t_gui_window *window, - struct t_gui_buffer *buffer, - struct t_hashtable *extra_info); - -int slack_buffer_nickcmp_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *nick1, - const char *nick2); - -int slack_buffer_close_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer); - -#endif /*SLACK_BUFFER_H*/ diff --git a/slack-channel.c b/slack-channel.c deleted file mode 100644 index 33efb9e..0000000 --- a/slack-channel.c +++ /dev/null @@ -1,642 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-workspace.h" -#include "slack-user.h" -#include "slack-channel.h" -#include "slack-input.h" -#include "slack-buffer.h" - -struct t_slack_channel *slack_channel_search(struct t_slack_workspace *workspace, - const char *id) -{ - struct t_slack_channel *ptr_channel; - - if (!workspace || !id) - return NULL; - - for (ptr_channel = workspace->channels; ptr_channel; - ptr_channel = ptr_channel->next_channel) - { - if (weechat_strcasecmp(ptr_channel->id, id) == 0) - return ptr_channel; - } - - return NULL; -} - -struct t_gui_buffer *slack_channel_search_buffer(struct t_slack_workspace *workspace, - enum t_slack_channel_type type, - const char *name) -{ - struct t_hdata *hdata_buffer; - struct t_gui_buffer *ptr_buffer; - const char *ptr_type, *ptr_workspace_name, *ptr_channel_name; - - hdata_buffer = weechat_hdata_get("buffer"); - ptr_buffer = weechat_hdata_get_list(hdata_buffer, "gui_buffers"); - - while (ptr_buffer) - { - if (weechat_buffer_get_pointer(ptr_buffer, "plugin") == weechat_slack_plugin) - { - ptr_type = weechat_buffer_get_string(ptr_buffer, "localvar_type"); - ptr_workspace_name = weechat_buffer_get_string(ptr_buffer, - "localvar_server"); - ptr_channel_name = weechat_buffer_get_string(ptr_buffer, - "localvar_channel"); - if (ptr_type && ptr_type[0] - && ptr_workspace_name && ptr_workspace_name[0] - && ptr_channel_name && ptr_channel_name[0] - && ( (( (type == SLACK_CHANNEL_TYPE_CHANNEL) - || (type == SLACK_CHANNEL_TYPE_GROUP)) - && (strcmp(ptr_type, "channel") == 0)) - || (( (type == SLACK_CHANNEL_TYPE_MPIM) - || (type == SLACK_CHANNEL_TYPE_IM)) - && (strcmp(ptr_type, "private") == 0))) - && (strcmp(ptr_workspace_name, workspace->domain) == 0) - && (weechat_strcasecmp(ptr_channel_name, name) == 0)) - { - return ptr_buffer; - } - } - ptr_buffer = weechat_hdata_move(hdata_buffer, ptr_buffer, 1); - } - - return NULL; -} - -struct t_gui_buffer *slack_channel_create_buffer(struct t_slack_workspace *workspace, - enum t_slack_channel_type type, - const char *name) -{ - struct t_gui_buffer *ptr_buffer; - int buffer_created; - const char *short_name, *localvar_channel; - char buffer_name[256]; - - buffer_created = 0; - - snprintf(buffer_name, sizeof(buffer_name), - "%s.%s", workspace->domain, name); - - ptr_buffer = slack_channel_search_buffer(workspace, type, name); - if (ptr_buffer) - { - weechat_nicklist_remove_all(ptr_buffer); - } - else - { - ptr_buffer = weechat_buffer_new(buffer_name, - &slack_input_data_cb, NULL, NULL, - &slack_buffer_close_cb, NULL, NULL); - if (!ptr_buffer) - return NULL; - - buffer_created = 1; - } - - if (buffer_created) - { - if (!weechat_buffer_get_integer(ptr_buffer, "short_name_is_set")) - weechat_buffer_set(ptr_buffer, "short_name", name); - } - else - { - short_name = weechat_buffer_get_string (ptr_buffer, "short_name"); - localvar_channel = weechat_buffer_get_string (ptr_buffer, - "localvar_channel"); - - if (!short_name || - (localvar_channel && (strcmp(localvar_channel, short_name) == 0))) - { - weechat_buffer_set (ptr_buffer, "short_name", name); - } - } - - weechat_buffer_set(ptr_buffer, "name", buffer_name); - weechat_buffer_set(ptr_buffer, "localvar_set_type", - (type == SLACK_CHANNEL_TYPE_IM || - type == SLACK_CHANNEL_TYPE_MPIM) ? "private" : "channel"); - weechat_buffer_set(ptr_buffer, "localvar_set_nick", workspace->nick); - weechat_buffer_set(ptr_buffer, "localvar_set_server", workspace->domain); - weechat_buffer_set(ptr_buffer, "localvar_set_channel", name); - - if (buffer_created) - { - (void) weechat_hook_signal_send ("logger_backlog", - WEECHAT_HOOK_SIGNAL_POINTER, - ptr_buffer); - weechat_buffer_set(ptr_buffer, "input_get_unknown_commands", "1"); - if (type != SLACK_CHANNEL_TYPE_IM) - { - weechat_buffer_set(ptr_buffer, "nicklist", "1"); - weechat_buffer_set(ptr_buffer, "nicklist_display_groups", "0"); - weechat_buffer_set_pointer(ptr_buffer, "nicklist_callback", - &slack_buffer_nickcmp_cb); - weechat_buffer_set_pointer(ptr_buffer, "nicklist_callback_pointer", - workspace); - } - - weechat_buffer_set(ptr_buffer, "highlight_words_add", - workspace->nick); - weechat_buffer_set(ptr_buffer, "highlight_tags_restrict", - "slack_message"); - } - - return ptr_buffer; -} - -void slack_channel_add_nicklist_groups(struct t_slack_workspace *workspace, - struct t_slack_channel *channel) -{ - struct t_gui_buffer *ptr_buffer; - char str_group[32]; - - if (channel && channel->type == SLACK_CHANNEL_TYPE_MPIM) - return; - if (channel && channel->type == SLACK_CHANNEL_TYPE_IM) - return; - - ptr_buffer = channel ? channel->buffer : workspace->buffer; - - snprintf(str_group, sizeof(str_group), "%03d|%s", - 000, "+"); - weechat_nicklist_add_group(ptr_buffer, NULL, str_group, - "weechat.color.nicklist_group", 1); - snprintf(str_group, sizeof(str_group), "%03d|%s", - 999, "..."); - weechat_nicklist_add_group(ptr_buffer, NULL, str_group, - "weechat.color.nicklist_group", 1); -} - -struct t_slack_channel *slack_channel_new(struct t_slack_workspace *workspace, - enum t_slack_channel_type type, - const char *id, const char *name) -{ - struct t_slack_channel *new_channel, *ptr_channel; - struct t_gui_buffer *ptr_buffer; - struct t_hook *typing_timer; - char buffer_name[SLACK_CHANNEL_NAME_MAX_LEN + 2]; - - if (!workspace || !id || !name || !name[0]) - return NULL; - - ptr_channel = slack_channel_search(workspace, id); - if (ptr_channel) - { - return ptr_channel; - } - - buffer_name[0] = '#'; - strncpy(&buffer_name[1], name, SLACK_CHANNEL_NAME_MAX_LEN + 1); - - ptr_buffer = slack_channel_create_buffer(workspace, type, buffer_name); - if (!ptr_buffer) - return NULL; - - if ((new_channel = malloc(sizeof(*new_channel))) == NULL) - return NULL; - - typing_timer = weechat_hook_timer(1 * 1000, 0, 0, - &slack_channel_typing_cb, - new_channel, NULL); - - new_channel->type = type; - new_channel->id = strdup(id); - new_channel->name = strdup(name); - new_channel->created = 0; - - new_channel->is_general = 0; - new_channel->name_normalized = NULL; - new_channel->is_shared = 0; - new_channel->is_org_shared = 0; - new_channel->is_member = 0; - - new_channel->topic.value = NULL; - new_channel->topic.creator = NULL; - new_channel->topic.last_set = 0; - new_channel->purpose.value = NULL; - new_channel->purpose.creator = NULL; - new_channel->purpose.last_set = 0; - new_channel->is_archived = 0; - - new_channel->creator = NULL; - new_channel->last_read = 0.0; - new_channel->unread_count = 0; - new_channel->unread_count_display = 0; - - new_channel->is_user_deleted = 0; - - new_channel->typing_hook_timer = typing_timer; - new_channel->members_speaking[0] = NULL; - new_channel->members_speaking[1] = NULL; - new_channel->typings = NULL; - new_channel->last_typing = NULL; - new_channel->members = NULL; - new_channel->last_member = NULL; - new_channel->buffer = ptr_buffer; - new_channel->buffer_as_string = NULL; - - new_channel->prev_channel = workspace->last_channel; - new_channel->next_channel = NULL; - if (workspace->last_channel) - (workspace->last_channel)->next_channel = new_channel; - else - workspace->channels = new_channel; - workspace->last_channel = new_channel; - - return new_channel; -} - -void slack_channel_member_speaking_add_to_list(struct t_slack_channel *channel, - const char *nick, - int highlight) -{ - int size, to_remove, i; - struct t_weelist_item *ptr_item; - - /* create list if it does not exist */ - if (!channel->members_speaking[highlight]) - channel->members_speaking[highlight] = weechat_list_new(); - - /* remove item if it was already in list */ - ptr_item = weechat_list_casesearch(channel->members_speaking[highlight], nick); - if (ptr_item) - weechat_list_remove(channel->members_speaking[highlight], ptr_item); - - /* add nick in list */ - weechat_list_add(channel->members_speaking[highlight], nick, - WEECHAT_LIST_POS_END, NULL); - - /* reduce list size if it's too big */ - size = weechat_list_size(channel->members_speaking[highlight]); - if (size > SLACK_CHANNEL_MEMBERS_SPEAKING_LIMIT) - { - to_remove = size - SLACK_CHANNEL_MEMBERS_SPEAKING_LIMIT; - for (i = 0; i < to_remove; i++) - { - weechat_list_remove( - channel->members_speaking[highlight], - weechat_list_get(channel->members_speaking[highlight], 0)); - } - } -} - -void slack_channel_member_speaking_add(struct t_slack_channel *channel, - const char *nick, int highlight) -{ - if (highlight < 0) - highlight = 0; - if (highlight > 1) - highlight = 1; - if (highlight) - slack_channel_member_speaking_add_to_list(channel, nick, 1); - - slack_channel_member_speaking_add_to_list(channel, nick, 0); -} - -void slack_channel_member_speaking_rename(struct t_slack_channel *channel, - const char *old_nick, - const char *new_nick) -{ - struct t_weelist_item *ptr_item; - int i; - - for (i = 0; i < 2; i++) - { - if (channel->members_speaking[i]) - { - ptr_item = weechat_list_search(channel->members_speaking[i], old_nick); - if (ptr_item) - weechat_list_set(ptr_item, new_nick); - } - } -} - -void slack_channel_member_speaking_rename_if_present(struct t_slack_workspace *workspace, - struct t_slack_channel *channel, - const char *nick) -{ - struct t_weelist_item *ptr_item; - int i, j, list_size; - - (void) workspace; - - for (i = 0; i < 2; i++) - { - if (channel->members_speaking[i]) - { - list_size = weechat_list_size(channel->members_speaking[i]); - for (j = 0; j < list_size; j++) - { - ptr_item = weechat_list_get (channel->members_speaking[i], j); - if (ptr_item && (strcasecmp(weechat_list_string(ptr_item), nick) == 0)) - weechat_list_set(ptr_item, nick); - } - } - } -} - -void slack_channel_typing_free(struct t_slack_channel *channel, - struct t_slack_channel_typing *typing) -{ - struct t_slack_channel_typing *new_typings; - - if (!channel || !typing) - return; - - /* remove typing from typings list */ - if (channel->last_typing == typing) - channel->last_typing = typing->prev_typing; - if (typing->prev_typing) - { - (typing->prev_typing)->next_typing = typing->next_typing; - new_typings = channel->typings; - } - else - new_typings = typing->next_typing; - - if (typing->next_typing) - (typing->next_typing)->prev_typing = typing->prev_typing; - - /* free typing data */ - if (typing->id) - free(typing->id); - if (typing->name) - free(typing->name); - - free(typing); - - channel->typings = new_typings; -} - -void slack_channel_typing_free_all(struct t_slack_channel *channel) -{ - while (channel->typings) - slack_channel_typing_free(channel, channel->typings); -} - -int slack_channel_typing_cb(const void *pointer, - void *data, - int remaining_calls) -{ - struct t_slack_channel_typing *ptr_typing, *next_typing; - struct t_slack_channel *channel; - const char *localvar; - unsigned typecount; - time_t now; - - (void) data; - (void) remaining_calls; - - if (!pointer) - return WEECHAT_RC_ERROR; - - channel = (struct t_slack_channel *)pointer; - - now = time(NULL); - - typecount = 0; - - for (ptr_typing = channel->typings; ptr_typing; - ptr_typing = ptr_typing->next_typing) - { - next_typing = ptr_typing->next_typing; - - while (ptr_typing && now - ptr_typing->ts > 5) - { - slack_channel_typing_free(channel, ptr_typing); - ptr_typing = next_typing; - if (ptr_typing) - next_typing = ptr_typing->next_typing; - } - - if (!ptr_typing) - break; - - typecount++; - } - - localvar = weechat_buffer_get_string(channel->buffer, "localvar_typing"); - if (!localvar || strncmp(localvar, typecount > 0 ? "1" : "0", 1) != 0) - weechat_buffer_set(channel->buffer, - "localvar_set_typing", - typecount > 0 ? "1" : "0"); - weechat_bar_item_update("slack_typing"); - - return WEECHAT_RC_OK; -} - -struct t_slack_channel_typing *slack_channel_typing_search( - struct t_slack_channel *channel, - const char *id) -{ - struct t_slack_channel_typing *ptr_typing; - - if (!channel || !id) - return NULL; - - for (ptr_typing = channel->typings; ptr_typing; - ptr_typing = ptr_typing->next_typing) - { - if (weechat_strcasecmp(ptr_typing->id, id) == 0) - return ptr_typing; - } - - return NULL; -} - -void slack_channel_add_typing(struct t_slack_channel *channel, - struct t_slack_user *user) -{ - struct t_slack_channel_typing *new_typing; - - new_typing = slack_channel_typing_search(channel, user->id); - if (!new_typing) - { - new_typing = malloc(sizeof(*new_typing)); - new_typing->id = strdup(user->id); - new_typing->name = strdup(user->profile.display_name); - - new_typing->prev_typing = channel->last_typing; - new_typing->next_typing = NULL; - if (channel->last_typing) - (channel->last_typing)->next_typing = new_typing; - else - channel->typings = new_typing; - channel->last_typing = new_typing; - } - new_typing->ts = time(NULL); - - slack_channel_typing_cb(channel, NULL, 0); -} - -void slack_channel_member_free(struct t_slack_channel *channel, - struct t_slack_channel_member *member) -{ - struct t_slack_channel_member *new_members; - - if (!channel || !member) - return; - - /* remove member from members list */ - if (channel->last_member == member) - channel->last_member = member->prev_member; - if (member->prev_member) - { - (member->prev_member)->next_member = member->next_member; - new_members = channel->members; - } - else - new_members = member->next_member; - - if (member->next_member) - (member->next_member)->prev_member = member->prev_member; - - /* free member data */ - if (member->id) - free(member->id); - - free(member); - - channel->members = new_members; -} - -void slack_channel_member_free_all(struct t_slack_channel *channel) -{ - while (channel->members) - slack_channel_member_free(channel, channel->members); -} - -void slack_channel_free(struct t_slack_workspace *workspace, - struct t_slack_channel *channel) -{ - struct t_slack_channel *new_channels; - - if (!workspace || !channel) - return; - - /* remove channel from channels list */ - if (workspace->last_channel == channel) - workspace->last_channel = channel->prev_channel; - if (channel->prev_channel) - { - (channel->prev_channel)->next_channel = channel->next_channel; - new_channels = workspace->channels; - } - else - new_channels = channel->next_channel; - - if (channel->next_channel) - (channel->next_channel)->prev_channel = channel->prev_channel; - - /* free hooks */ - if (channel->typing_hook_timer) - weechat_unhook(channel->typing_hook_timer); - - /* free linked lists */ - slack_channel_typing_free_all(channel); - slack_channel_member_free_all(channel); - - /* free channel data */ - if (channel->id) - free(channel->id); - if (channel->name) - free(channel->name); - if (channel->name_normalized) - free(channel->name_normalized); - if (channel->topic.value) - free(channel->topic.value); - if (channel->topic.creator) - free(channel->topic.creator); - if (channel->purpose.value) - free(channel->purpose.value); - if (channel->purpose.creator) - free(channel->purpose.creator); - if (channel->creator) - free(channel->creator); - if (channel->members_speaking[0]) - weechat_list_free(channel->members_speaking[0]); - if (channel->members_speaking[1]) - weechat_list_free(channel->members_speaking[1]); - if (channel->buffer_as_string) - free(channel->buffer_as_string); - - free(channel); - - workspace->channels = new_channels; -} - -void slack_channel_free_all(struct t_slack_workspace *workspace) -{ - while (workspace->channels) - slack_channel_free(workspace, workspace->channels); -} - -void slack_channel_update_topic(struct t_slack_channel *channel, - const char* topic, - const char* creator, - int last_set) -{ - if (channel->topic.value) - free(channel->topic.value); - if (channel->topic.creator) - free(channel->topic.creator); - channel->topic.value = (topic) ? strdup(topic) : NULL; - channel->topic.creator = (creator) ? strdup(creator) : NULL; - channel->topic.last_set = last_set; - - if (channel->topic.value) - weechat_buffer_set(channel->buffer, "title", topic); - else - weechat_buffer_set(channel->buffer, "title", ""); -} - -void slack_channel_update_purpose(struct t_slack_channel *channel, - const char* purpose, - const char* creator, - int last_set) -{ - if (channel->purpose.value) - free(channel->purpose.value); - if (channel->purpose.creator) - free(channel->purpose.creator); - channel->purpose.value = (purpose) ? strdup(purpose) : NULL; - channel->purpose.creator = (creator) ? strdup(creator) : NULL; - channel->purpose.last_set = last_set; -} - -struct t_slack_channel_member *slack_channel_add_member( - struct t_slack_workspace *workspace, - struct t_slack_channel *channel, - const char *id) -{ - struct t_slack_channel_member *member; - struct t_slack_user *user; - - member = malloc(sizeof(struct t_slack_channel_member)); - member->id = strdup(id); - - member->prev_member = channel->last_member; - member->next_member = NULL; - if (channel->last_member) - (channel->last_member)->next_member = member; - else - channel->members = member; - channel->last_member = member; - - user = slack_user_search(workspace, id); - if (user) - slack_user_nicklist_add(workspace, channel, user); - - return member; -} diff --git a/slack-channel.h b/slack-channel.h deleted file mode 100644 index e5f507e..0000000 --- a/slack-channel.h +++ /dev/null @@ -1,147 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_CHANNEL_H_ -#define _SLACK_CHANNEL_H_ - -#define SLACK_CHANNEL_MEMBERS_SPEAKING_LIMIT 128 - -#define SLACK_CHANNEL_NAME_MAX_LEN 22 - -enum t_slack_channel_type -{ - SLACK_CHANNEL_TYPE_CHANNEL, - SLACK_CHANNEL_TYPE_GROUP, - SLACK_CHANNEL_TYPE_MPIM, - SLACK_CHANNEL_TYPE_IM, -}; - -struct t_slack_channel_typing -{ - char *id; - char *name; - time_t ts; - - struct t_slack_channel_typing *prev_typing; - struct t_slack_channel_typing *next_typing; -}; - -struct t_slack_channel_member -{ - char *id; - - struct t_slack_channel_member *prev_member; - struct t_slack_channel_member *next_member; -}; - -struct t_slack_channel_topic -{ - char *value; - char *creator; - time_t last_set; -}; - -struct t_slack_channel_purpose -{ - char *value; - char *creator; - time_t last_set; -}; - -struct t_slack_channel -{ - enum t_slack_channel_type type; - char *id; - char *name; - time_t created; - - /* channel */ - int is_general; - char *name_normalized; - int is_shared; - int is_org_shared; - int is_member; - - /* group */ - struct t_slack_channel_topic topic; - struct t_slack_channel_purpose purpose; - int is_archived; - - /* mpim */ - char *creator; - double last_read; - int unread_count; - int unread_count_display; - - /* im */ - int is_user_deleted; - - struct t_hook *typing_hook_timer; - struct t_weelist *members_speaking[2]; - struct t_slack_channel_typing *typings; - struct t_slack_channel_typing *last_typing; - struct t_slack_channel_member *members; - struct t_slack_channel_member *last_member; - struct t_gui_buffer *buffer; - char *buffer_as_string; - - struct t_slack_channel *prev_channel; - struct t_slack_channel *next_channel; -}; - -struct t_slack_channel *slack_channel_search(struct t_slack_workspace *workspace, - const char *id); - -void slack_channel_add_nicklist_groups(struct t_slack_workspace *workspace, - struct t_slack_channel *channel); - -struct t_slack_channel *slack_channel_new(struct t_slack_workspace *workspace, - enum t_slack_channel_type type, - const char *id, const char *name); - -void slack_channel_member_speaking_add(struct t_slack_channel *channel, - const char *nick, int highlight); - -void slack_channel_member_speaking_rename(struct t_slack_channel *channel, - const char *old_nick, - const char *new_nick); - -void slack_channel_member_speaking_rename_if_present(struct t_slack_workspace *workspace, - struct t_slack_channel *channel, - const char *nick); - -void slack_channel_typing_free(struct t_slack_channel *channel, - struct t_slack_channel_typing *typing); - -void slack_channel_typing_free_all(struct t_slack_channel *channel); - -int slack_channel_typing_cb(const void *pointer, - void *data, - int remaining_calls); - -struct t_slack_channel_typing *slack_channel_typing_search( - struct t_slack_channel *channel, - const char *id); - -void slack_channel_add_typing(struct t_slack_channel *channel, - struct t_slack_user *user); - -void slack_channel_free_all(struct t_slack_workspace *workspace); - -void slack_channel_update_topic(struct t_slack_channel *channel, - const char* title, - const char* creator, - int last_set); - -void slack_channel_update_purpose(struct t_slack_channel *channel, - const char* purpose, - const char* creator, - int last_set); - -struct t_slack_channel_member *slack_channel_add_member( - struct t_slack_workspace *workspace, - struct t_slack_channel *channel, - const char *id); - -#endif /*SLACK_CHANNEL_H*/ diff --git a/slack-completion.c b/slack-completion.c deleted file mode 100644 index c8c6e80..0000000 --- a/slack-completion.c +++ /dev/null @@ -1,162 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-config.h" -#include "slack-emoji.h" -#include "slack-workspace.h" -#include "slack-channel.h" -#include "slack-user.h" -#include "slack-buffer.h" -#include "slack-completion.h" - -void slack_completion_channel_nicks_add_speakers(struct t_gui_completion *completion, - struct t_slack_workspace *workspace, - struct t_slack_channel *channel, - int highlight) -{ - struct t_slack_user *user; - const char *member; - int list_size, i; - - if (channel->members_speaking[highlight]) - { - list_size = weechat_list_size(channel->members_speaking[highlight]); - for (i = 0; i < list_size; i++) - { - member = weechat_list_string ( - weechat_list_get(channel->members_speaking[highlight], i)); - if (member) - { - user = slack_user_search(workspace, member); - if (user) - weechat_hook_completion_list_add(completion, - user->profile.display_name, - 1, WEECHAT_LIST_POS_BEGINNING); - } - } - } -} - -int slack_completion_channel_nicks_cb(const void *pointer, void *data, - const char *completion_item, - struct t_gui_buffer *buffer, - struct t_gui_completion *completion) -{ - struct t_slack_workspace *ptr_workspace; - struct t_slack_channel *ptr_channel; - struct t_slack_channel_member *ptr_member; - struct t_slack_user *ptr_user; - - - (void) pointer; - (void) data; - (void) completion_item; - - ptr_workspace = NULL; - ptr_channel = NULL; - slack_buffer_get_workspace_and_channel(buffer, &ptr_workspace, &ptr_channel); - - if (ptr_channel) - { - switch (ptr_channel->type) - { - case SLACK_CHANNEL_TYPE_CHANNEL: - case SLACK_CHANNEL_TYPE_GROUP: - case SLACK_CHANNEL_TYPE_MPIM: - case SLACK_CHANNEL_TYPE_IM: - for (ptr_member = ptr_channel->members; ptr_member; - ptr_member = ptr_member->next_member) - { - ptr_user = slack_user_search(ptr_workspace, ptr_member->id); - if (ptr_user) - weechat_hook_completion_list_add(completion, - ptr_user->profile.display_name, - 1, WEECHAT_LIST_POS_SORT); - } - /* add recent speakers on channel */ - if (weechat_config_integer(slack_config_look_nick_completion_smart) == SLACK_CONFIG_NICK_COMPLETION_SMART_SPEAKERS) - { - slack_completion_channel_nicks_add_speakers(completion, ptr_workspace, ptr_channel, 0); - } - /* add members whose make highlights on me recently on this channel */ - if (weechat_config_integer(slack_config_look_nick_completion_smart) == SLACK_CONFIG_NICK_COMPLETION_SMART_SPEAKERS_HIGHLIGHTS) - { - slack_completion_channel_nicks_add_speakers(completion, ptr_workspace, ptr_channel, 1); - } - /* add self member at the end */ - weechat_hook_completion_list_add(completion, - ptr_workspace->nick, - 1, WEECHAT_LIST_POS_END); - break; - } - } - - return WEECHAT_RC_OK; -} - -int slack_completion_workspaces_cb(const void *pointer, void *data, - const char *completion_item, - struct t_gui_buffer *buffer, - struct t_gui_completion *completion) -{ - struct t_slack_workspace *ptr_workspace; - - - (void) pointer; - (void) data; - (void) completion_item; - (void) buffer; - - for (ptr_workspace = slack_workspaces; ptr_workspace; - ptr_workspace = ptr_workspace->next_workspace) - { - weechat_hook_completion_list_add(completion, ptr_workspace->domain, - 0, WEECHAT_LIST_POS_SORT); - } - - return WEECHAT_RC_OK; -} - -void slack_completion_init() -{ - struct t_config_option *option; - const char *default_template; - - - weechat_hook_completion ("nick", - N_("nicks of current Slack channel"), - &slack_completion_channel_nicks_cb, - NULL, NULL); - - weechat_hook_completion("slack_workspace", - N_("slack workspaces"), - &slack_completion_workspaces_cb, - NULL, NULL); - - weechat_hook_completion("slack_emoji", - N_("slack emoji"), - &slack_emoji_complete_by_name_cb, - NULL, NULL); - - option = weechat_config_get("weechat.completion.default_template"); - default_template = weechat_config_string(option); - if (!weechat_strcasestr(default_template, "%(slack_emoji)")) - { - size_t length = snprintf(NULL, 0, "%s|%s", - default_template, - "%(slack_emoji)") + 1; - char *new_template = malloc(length); - snprintf(new_template, length, "%s|%s", - default_template, - "%(slack_emoji)"); - weechat_config_option_set(option, new_template, 1); - free(new_template); - } -} diff --git a/slack-completion.h b/slack-completion.h deleted file mode 100644 index 5ae559f..0000000 --- a/slack-completion.h +++ /dev/null @@ -1,10 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_COMPLETION_H_ -#define _SLACK_COMPLETION_H_ - -void slack_completion_init(); - -#endif /*SLACK_COMPLETION_H*/ diff --git a/slack-emoji.c b/slack-emoji.c deleted file mode 100644 index 3ec6802..0000000 --- a/slack-emoji.c +++ /dev/null @@ -1,289 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-workspace.h" -#include "slack-channel.h" -#include "slack-buffer.h" -#include "slack-emoji.h" - -#include "slack-emoji.inc" - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -static int emoji_byname_cmp(const void *p1, const void *p2) -{ - return strcasecmp(((struct t_slack_emoji_by_name *)p1)->name, - ((struct t_slack_emoji_by_name *)p2)->name); -} - -static int emoji_bytext_cmp(const void *p1, const void *p2) -{ - return strcasecmp(((struct t_slack_emoji_by_text *)p1)->text, - ((struct t_slack_emoji_by_text *)p2)->text); -} - -static size_t modified_wagner_fischer(const char *src, const char *targ) -{ - size_t len = strlen(targ) + 1; - size_t above[len], below[len]; - for (size_t *k = above, c = 0; k < above + len; ++k, ++c) *k = c; - - const char *src_at = src, *targ_at; - for (size_t j = 1; j < strlen(src) + 1; ++j) - { - *below = j; - targ_at = targ; - for (size_t *d = above, *a = above + 1, *l = below, *c = below + 1; - c < below + len; ++d, ++a, ++l, ++c) - { - /* |-------------replace-----------| |isrt| |delt| */ - *c = MIN( *src_at == *targ_at ? *d : *d + 1, MIN( *a + 0, *l + 1 ) ); - ++targ_at; - } - for (size_t *a = above, *b = below; a < above + len; ++a, ++b) *a = *b; - ++src_at; - } - - return above[len-1]; -} - -static size_t longest_common_substring(const char *X, const char *Y) -{ - const size_t n = strlen(X); - const size_t m = strlen(Y); - size_t i, j, result = 0; - size_t **L; - - L = malloc(sizeof(size_t *) * (n + 1)); - L[0] = malloc(sizeof(size_t) * (m + 1) * (n + 1)); - - for (i = 0; i <= n; i++) - L[i] = (*L + (m + 1) * i); - - /* Following steps build L[n+1][m+1] in bottom up fashion. Note - that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */ - for (i = 0; i <= n; i++) - { - for (j = 0; j <= m; j++) - { - if (i == 0 || j == 0) - { - L[i][j] = 0; - } - else if (X[i-1] == Y[j-1]) - { - L[i][j] = L[i - 1][j - 1] + 1; - if (result < L[i][j]) - result = L[i][j]; - } - else - { - L[i][j] = 0; - } - } - } - - /* result now contains length of LCS for X[0..n-1] and Y[0..m-1] */ - free(L[0]); - free(L); - return result; -} - -int slack_emoji_complete_by_name_cb(const void *pointer, void *data, - const char *completion_item, - struct t_gui_buffer *buffer, - struct t_gui_completion *completion) -{ - struct t_slack_workspace_emoji *ptr_emoji; - struct t_slack_workspace *workspace; - struct t_slack_channel *channel; - - (void) pointer; - (void) data; - (void) completion_item; - - workspace = NULL; - slack_buffer_get_workspace_and_channel(buffer, &workspace, &channel); - - size_t i, emoji_count = sizeof(slack_emoji_by_name) - / sizeof(struct t_slack_emoji_by_name); - - if (workspace) - { - for (ptr_emoji = workspace->emoji; ptr_emoji; - ptr_emoji = ptr_emoji->next_emoji) - weechat_hook_completion_list_add(completion, - ptr_emoji->name, - 0, WEECHAT_LIST_POS_END); - - for (i = 0; i < emoji_count; i++) - weechat_hook_completion_list_add(completion, - slack_emoji_by_name[i].name, - 0, WEECHAT_LIST_POS_END); - } - - return WEECHAT_RC_OK; -} - -int slack_emoji_input_complete_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *command) -{ - struct t_slack_emoji_by_name *closest_emoji; - int input_pos, input_length, start, end; - char *new_string, *word, *new_pos; - const char *input_string; - - (void) pointer; - (void) data; - (void) command; - - input_string = weechat_buffer_get_string(buffer, "input"); - input_length = strlen(input_string); - input_pos = weechat_buffer_get_integer(buffer, "input_pos"); - for (start = input_pos; start > 0 && input_string[start] != ':'; start--) - if (input_string[start] == ' ') { break; } - for (end = input_pos; end < input_length && input_string[end] != ' '; end++) - if (input_string[end] == ':') { end++; break; } - - if (input_string[start] != ':') - return WEECHAT_RC_OK; - else - word = strndup(&input_string[start], end - start); - - size_t emoji_count = sizeof(slack_emoji_by_name) - / sizeof(struct t_slack_emoji_by_name); - closest_emoji = malloc(sizeof(slack_emoji_by_name)); - memcpy(closest_emoji, slack_emoji_by_name, - sizeof(slack_emoji_by_name)); - - int edit_dist_cmp(const void *p1, const void *p2) - { - const struct t_slack_emoji_by_name *e1 = p1; - const struct t_slack_emoji_by_name *e2 = p2; - size_t d1 = modified_wagner_fischer(e1->name, word); - size_t d2 = modified_wagner_fischer(e2->name, word); - if (d1 == d2) - { - size_t l1 = longest_common_substring(e1->name, word); - size_t l2 = longest_common_substring(e2->name, word); - return (l1 < l2) - (l1 > l2); - } - return (d1 > d2) - (d1 < d2); - }; - qsort(closest_emoji, emoji_count, - sizeof(struct t_slack_emoji_by_name), - edit_dist_cmp); - - size_t new_length = snprintf(NULL, 0, "%.*s%s%s", - start, input_string, - closest_emoji[0].name, - &input_string[end]) + 1; - new_string = malloc(new_length); - snprintf(new_string, new_length, "%.*s%s%s", - start, input_string, - closest_emoji[0].name, - &input_string[end]); - weechat_buffer_set(buffer, "input", new_string); - - size_t new_pos_len = snprintf(NULL, 0, "%lu", - (unsigned long)(start + - strlen(closest_emoji[0].name) - 1)); - new_pos = malloc(new_pos_len); - snprintf(new_pos, new_pos_len, "%lu", - (unsigned long)(start + - strlen(closest_emoji[0].name) - 1)); - weechat_buffer_set(buffer, "input_pos", new_pos); - - free(new_pos); - free(new_string); - free(closest_emoji); - free(word); - return WEECHAT_RC_OK_EAT; -} - -int slack_emoji_input_replace_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *command) -{ - (void) pointer; - (void) data; - (void) buffer; - (void) command; - - /* TBI */ - - return WEECHAT_RC_OK; -} - -const char *slack_emoji_get_unicode_by_name(const char *name) -{ - struct t_slack_emoji_by_name *result; - struct t_slack_emoji_by_name key; - key.name = name; - - size_t emoji_count = sizeof(slack_emoji_by_name) - / sizeof(struct t_slack_emoji_by_name); - result = (struct t_slack_emoji_by_name *)bsearch( - &key, slack_emoji_by_name, emoji_count, - sizeof(struct t_slack_emoji_by_name), - emoji_byname_cmp); - - return result->unicode; -} - -const char *slack_emoji_get_unicode_by_text(const char *text) -{ - struct t_slack_emoji_by_text *result; - struct t_slack_emoji_by_text key; - key.text = text; - - size_t emoji_count = sizeof(slack_emoji_by_text) - / sizeof(struct t_slack_emoji_by_text); - result = (struct t_slack_emoji_by_text *)bsearch( - &key, slack_emoji_by_text, emoji_count, - sizeof(struct t_slack_emoji_by_text), - emoji_bytext_cmp); - - return result->unicode; -} - -const char *slack_emoji_get_text_by_name(const char *name) -{ - struct t_slack_emoji_by_name *result; - struct t_slack_emoji_by_name key; - key.name = name; - - size_t emoji_count = sizeof(slack_emoji_by_name) - / sizeof(struct t_slack_emoji_by_name); - result = (struct t_slack_emoji_by_name *)bsearch( - &key, slack_emoji_by_name, emoji_count, - sizeof(struct t_slack_emoji_by_name), - emoji_byname_cmp); - - return result->text_to; -} - -const char *slack_emoji_get_name_by_text(const char *text) -{ - struct t_slack_emoji_by_text *result; - struct t_slack_emoji_by_text key; - key.text = text; - - size_t emoji_count = sizeof(slack_emoji_by_text) - / sizeof(struct t_slack_emoji_by_text); - result = (struct t_slack_emoji_by_text *)bsearch( - &key, slack_emoji_by_text, emoji_count, - sizeof(struct t_slack_emoji_by_text), - emoji_bytext_cmp); - - return result->name_to; -} diff --git a/slack-emoji.h b/slack-emoji.h deleted file mode 100644 index 9fc688d..0000000 --- a/slack-emoji.h +++ /dev/null @@ -1,29 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_EMOJI_H_ -#define _SLACK_EMOJI_H_ - -int slack_emoji_complete_by_name_cb(const void *pointer, void *data, - const char *completion_item, - struct t_gui_buffer *buffer, - struct t_gui_completion *completion); - -int slack_emoji_input_complete_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *command); - -int slack_emoji_input_replace_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *command); - -const char *slack_emoji_get_unicode_by_name(const char *name); - -const char *slack_emoji_get_unicode_by_text(const char *text); - -const char *slack_emoji_get_text_by_name(const char *name); - -const char *slack_emoji_get_name_by_text(const char *text); - -#endif /*SLACK_EMOJI_H*/ diff --git a/slack-emoji.inc b/slack-emoji.inc deleted file mode 100644 index 23f0588..0000000 --- a/slack-emoji.inc +++ /dev/null @@ -1,1702 +0,0 @@ - -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#define MAX_TEXTS 7 -#define MAX_NAMES 4 - -struct t_slack_emoji_by_name { - const char *name; - const char *unicode; - const char *text_to; - const char *text_from[MAX_TEXTS]; -}; - -struct t_slack_emoji_by_text { - const char *text; - const char *unicode; - const char *name_to; - const char *name_from[MAX_NAMES]; -}; - -static struct t_slack_emoji_by_name slack_emoji_by_name[] = -{ { ":+1:", "\u1f44D", NULL, {NULL} } -, { ":-1:", "\u1f44E", NULL, {NULL} } -, { ":100:", "\u1f4aF", NULL, {NULL} } -, { ":1234:", "\u1f522", NULL, {NULL} } -, { ":8ball:", "\u1f3b1", NULL, {NULL} } -, { ":a:", "\u1f170\ufe0f", NULL, {NULL} } -, { ":ab:", "\u1f18E", NULL, {NULL} } -, { ":abc:", "\u1f524", NULL, {NULL} } -, { ":abcd:", "\u1f521", NULL, {NULL} } -, { ":accept:", "\u1f251", NULL, {NULL} } -, { ":admission_tickets:", "\u1f39F\ufe0f", NULL, {NULL} } -, { ":adult:", "\u1f9d1", NULL, {NULL} } -, { ":aerial_tramway:", "\u1f6a1", NULL, {NULL} } -, { ":airplane:", "\u2708\ufe0f", NULL, {NULL} } -, { ":airplane_arriving:", "\u1f6eC", NULL, {NULL} } -, { ":airplane_departure:", "\u1f6eB", NULL, {NULL} } -, { ":alarm_clock:", "\u23f0", NULL, {NULL} } -, { ":alembic:", "\u2697\ufe0f", NULL, {NULL} } -, { ":alien:", "\u1f47D", NULL, {NULL} } -, { ":ambulance:", "\u1f691", NULL, {NULL} } -, { ":amphora:", "\u1f3fA", NULL, {NULL} } -, { ":anchor:", "\u2693", NULL, {NULL} } -, { ":angel:", "\u1f47C", NULL, {NULL} } -, { ":anger:", "\u1f4a2", NULL, {NULL} } -, { ":angry:", "\u1f620", NULL, {">:(", ">:-(", NULL} } -, { ":anguished:", "\u1f627", NULL, {"D:", NULL} } -, { ":ant:", "\u1f41C", NULL, {NULL} } -, { ":apple:", "\u1f34E", NULL, {NULL} } -, { ":aquarius:", "\u2652", NULL, {NULL} } -, { ":aries:", "\u2648", NULL, {NULL} } -, { ":arrow_backward:", "\u25c0\ufe0f", NULL, {NULL} } -, { ":arrow_double_down:", "\u23ec", NULL, {NULL} } -, { ":arrow_double_up:", "\u23eb", NULL, {NULL} } -, { ":arrow_down:", "\u2b07\ufe0f", NULL, {NULL} } -, { ":arrow_down_small:", "\u1f53D", NULL, {NULL} } -, { ":arrow_forward:", "\u25b6\ufe0f", NULL, {NULL} } -, { ":arrow_heading_down:", "\u2935\ufe0f", NULL, {NULL} } -, { ":arrow_heading_up:", "\u2934\ufe0f", NULL, {NULL} } -, { ":arrow_left:", "\u2b05\ufe0f", NULL, {NULL} } -, { ":arrow_lower_left:", "\u2199\ufe0f", NULL, {NULL} } -, { ":arrow_lower_right:", "\u2198\ufe0f", NULL, {NULL} } -, { ":arrow_right:", "\u27a1\ufe0f", NULL, {NULL} } -, { ":arrow_right_hook:", "\u21aa\ufe0f", NULL, {NULL} } -, { ":arrow_up:", "\u2b06\ufe0f", NULL, {NULL} } -, { ":arrow_up_down:", "\u2195\ufe0f", NULL, {NULL} } -, { ":arrow_up_small:", "\u1f53C", NULL, {NULL} } -, { ":arrow_upper_left:", "\u2196\ufe0f", NULL, {NULL} } -, { ":arrow_upper_right:", "\u2197\ufe0f", NULL, {NULL} } -, { ":arrows_clockwise:", "\u1f503", NULL, {NULL} } -, { ":arrows_counterclockwise:", "\u1f504", NULL, {NULL} } -, { ":art:", "\u1f3a8", NULL, {NULL} } -, { ":articulated_lorry:", "\u1f69B", NULL, {NULL} } -, { ":astonished:", "\u1f632", NULL, {NULL} } -, { ":athletic_shoe:", "\u1f45F", NULL, {NULL} } -, { ":atm:", "\u1f3e7", NULL, {NULL} } -, { ":atom_symbol:", "\u269b\ufe0f", NULL, {NULL} } -, { ":avocado:", "\u1f951", NULL, {NULL} } -, { ":b:", "\u1f171\ufe0f", NULL, {NULL} } -, { ":baby:", "\u1f476", NULL, {NULL} } -, { ":baby_bottle:", "\u1f37C", NULL, {NULL} } -, { ":baby_chick:", "\u1f424", NULL, {NULL} } -, { ":baby_symbol:", "\u1f6bC", NULL, {NULL} } -, { ":back:", "\u1f519", NULL, {NULL} } -, { ":bacon:", "\u1f953", NULL, {NULL} } -, { ":badminton_racquet_and_shuttlecock:", "\u1f3f8", NULL, {NULL} } -, { ":baggage_claim:", "\u1f6c4", NULL, {NULL} } -, { ":baguette_bread:", "\u1f956", NULL, {NULL} } -, { ":balloon:", "\u1f388", NULL, {NULL} } -, { ":ballot_box_with_ballot:", "\u1f5f3\ufe0f", NULL, {NULL} } -, { ":ballot_box_with_check:", "\u2611\ufe0f", NULL, {NULL} } -, { ":bamboo:", "\u1f38D", NULL, {NULL} } -, { ":banana:", "\u1f34C", NULL, {NULL} } -, { ":bangbang:", "\u203c\ufe0f", NULL, {NULL} } -, { ":bank:", "\u1f3e6", NULL, {NULL} } -, { ":bar_chart:", "\u1f4cA", NULL, {NULL} } -, { ":barber:", "\u1f488", NULL, {NULL} } -, { ":barely_sunny:", "\u1f325\ufe0f", NULL, {NULL} } -, { ":baseball:", "\u26be", NULL, {NULL} } -, { ":basketball:", "\u1f3c0", NULL, {NULL} } -, { ":bat:", "\u1f987", NULL, {NULL} } -, { ":bath:", "\u1f6c0", NULL, {NULL} } -, { ":bathtub:", "\u1f6c1", NULL, {NULL} } -, { ":battery:", "\u1f50B", NULL, {NULL} } -, { ":beach_with_umbrella:", "\u1f3d6\ufe0f", NULL, {NULL} } -, { ":bear:", "\u1f43B", NULL, {NULL} } -, { ":bearded_person:", "\u1f9d4", NULL, {NULL} } -, { ":bed:", "\u1f6cF\ufe0f", NULL, {NULL} } -, { ":bee:", "\u1f41D", NULL, {NULL} } -, { ":beer:", "\u1f37A", NULL, {NULL} } -, { ":beers:", "\u1f37B", NULL, {NULL} } -, { ":beetle:", "\u1f41E", NULL, {NULL} } -, { ":beginner:", "\u1f530", NULL, {NULL} } -, { ":bell:", "\u1f514", NULL, {NULL} } -, { ":bellhop_bell:", "\u1f6cE\ufe0f", NULL, {NULL} } -, { ":bento:", "\u1f371", NULL, {NULL} } -, { ":bicyclist:", "\u1f6b4", NULL, {NULL} } -, { ":bike:", "\u1f6b2", NULL, {NULL} } -, { ":bikini:", "\u1f459", NULL, {NULL} } -, { ":billed_cap:", "\u1f9e2", NULL, {NULL} } -, { ":biohazard_sign:", "\u2623\ufe0f", NULL, {NULL} } -, { ":bird:", "\u1f426", NULL, {NULL} } -, { ":birthday:", "\u1f382", NULL, {NULL} } -, { ":black_circle:", "\u26ab", NULL, {NULL} } -, { ":black_circle_for_record:", "\u23fa\ufe0f", NULL, {NULL} } -, { ":black_heart:", "\u1f5a4", NULL, {NULL} } -, { ":black_joker:", "\u1f0cF", NULL, {NULL} } -, { ":black_large_square:", "\u2b1b", NULL, {NULL} } -, { ":black_left_pointing_double_triangle_with_vertical_bar:", "\u23ee\ufe0f", NULL, {NULL} } -, { ":black_medium_small_square:", "\u25fe", NULL, {NULL} } -, { ":black_medium_square:", "\u25fc\ufe0f", NULL, {NULL} } -, { ":black_nib:", "\u2712\ufe0f", NULL, {NULL} } -, { ":black_right_pointing_double_triangle_with_vertical_bar:", "\u23ed\ufe0f", NULL, {NULL} } -, { ":black_right_pointing_triangle_with_double_vertical_bar:", "\u23ef\ufe0f", NULL, {NULL} } -, { ":black_small_square:", "\u25aa\ufe0f", NULL, {NULL} } -, { ":black_square_button:", "\u1f532", NULL, {NULL} } -, { ":black_square_for_stop:", "\u23f9\ufe0f", NULL, {NULL} } -, { ":blond-haired-man:", "\u1f471\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":blond-haired-woman:", "\u1f471\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":blossom:", "\u1f33C", NULL, {NULL} } -, { ":blowfish:", "\u1f421", NULL, {NULL} } -, { ":blue_book:", "\u1f4d8", NULL, {NULL} } -, { ":blue_car:", "\u1f699", NULL, {NULL} } -, { ":blue_heart:", "\u1f499", "<3", {NULL} } -, { ":blush:", "\u1f60A", ":)", {NULL} } -, { ":boar:", "\u1f417", NULL, {NULL} } -, { ":boat:", "\u26f5", NULL, {NULL} } -, { ":bomb:", "\u1f4a3", NULL, {NULL} } -, { ":book:", "\u1f4d6", NULL, {NULL} } -, { ":bookmark:", "\u1f516", NULL, {NULL} } -, { ":bookmark_tabs:", "\u1f4d1", NULL, {NULL} } -, { ":books:", "\u1f4dA", NULL, {NULL} } -, { ":boom:", "\u1f4a5", NULL, {NULL} } -, { ":boot:", "\u1f462", NULL, {NULL} } -, { ":bouquet:", "\u1f490", NULL, {NULL} } -, { ":bow:", "\u1f647", NULL, {NULL} } -, { ":bow_and_arrow:", "\u1f3f9", NULL, {NULL} } -, { ":bowl_with_spoon:", "\u1f963", NULL, {NULL} } -, { ":bowling:", "\u1f3b3", NULL, {NULL} } -, { ":boxing_glove:", "\u1f94A", NULL, {NULL} } -, { ":boy:", "\u1f466", NULL, {NULL} } -, { ":brain:", "\u1f9e0", NULL, {NULL} } -, { ":bread:", "\u1f35E", NULL, {NULL} } -, { ":breast-feeding:", "\u1f931", NULL, {NULL} } -, { ":bride_with_veil:", "\u1f470", NULL, {NULL} } -, { ":bridge_at_night:", "\u1f309", NULL, {NULL} } -, { ":briefcase:", "\u1f4bC", NULL, {NULL} } -, { ":broccoli:", "\u1f966", NULL, {NULL} } -, { ":broken_heart:", "\u1f494", "", ":->", NULL} } -, { ":leaves:", "\u1f343", NULL, {NULL} } -, { ":ledger:", "\u1f4d2", NULL, {NULL} } -, { ":left-facing_fist:", "\u1f91B", NULL, {NULL} } -, { ":left_luggage:", "\u1f6c5", NULL, {NULL} } -, { ":left_right_arrow:", "\u2194\ufe0f", NULL, {NULL} } -, { ":left_speech_bubble:", "\u1f5e8\ufe0f", NULL, {NULL} } -, { ":leftwards_arrow_with_hook:", "\u21a9\ufe0f", NULL, {NULL} } -, { ":lemon:", "\u1f34B", NULL, {NULL} } -, { ":leo:", "\u264c", NULL, {NULL} } -, { ":leopard:", "\u1f406", NULL, {NULL} } -, { ":level_slider:", "\u1f39A\ufe0f", NULL, {NULL} } -, { ":libra:", "\u264e", NULL, {NULL} } -, { ":light_rail:", "\u1f688", NULL, {NULL} } -, { ":lightning:", "\u1f329\ufe0f", NULL, {NULL} } -, { ":lightning_cloud:", "\u1f329\ufe0f", NULL, {NULL} } -, { ":link:", "\u1f517", NULL, {NULL} } -, { ":linked_paperclips:", "\u1f587\ufe0f", NULL, {NULL} } -, { ":lion_face:", "\u1f981", NULL, {NULL} } -, { ":lips:", "\u1f444", NULL, {NULL} } -, { ":lipstick:", "\u1f484", NULL, {NULL} } -, { ":lizard:", "\u1f98E", NULL, {NULL} } -, { ":lock:", "\u1f512", NULL, {NULL} } -, { ":lock_with_ink_pen:", "\u1f50F", NULL, {NULL} } -, { ":lollipop:", "\u1f36D", NULL, {NULL} } -, { ":loop:", "\u27bf", NULL, {NULL} } -, { ":loud_sound:", "\u1f50A", NULL, {NULL} } -, { ":loudspeaker:", "\u1f4e2", NULL, {NULL} } -, { ":love_hotel:", "\u1f3e9", NULL, {NULL} } -, { ":love_letter:", "\u1f48C", NULL, {NULL} } -, { ":low_brightness:", "\u1f505", NULL, {NULL} } -, { ":lower_left_ballpoint_pen:", "\u1f58A\ufe0f", NULL, {NULL} } -, { ":lower_left_crayon:", "\u1f58D\ufe0f", NULL, {NULL} } -, { ":lower_left_fountain_pen:", "\u1f58B\ufe0f", NULL, {NULL} } -, { ":lower_left_paintbrush:", "\u1f58C\ufe0f", NULL, {NULL} } -, { ":lying_face:", "\u1f925", NULL, {NULL} } -, { ":m:", "\u24c2\ufe0f", NULL, {NULL} } -, { ":mag:", "\u1f50D", NULL, {NULL} } -, { ":mag_right:", "\u1f50E", NULL, {NULL} } -, { ":mage:", "\u1f9d9", NULL, {NULL} } -, { ":mahjong:", "\u1f004", NULL, {NULL} } -, { ":mailbox:", "\u1f4eB", NULL, {NULL} } -, { ":mailbox_closed:", "\u1f4eA", NULL, {NULL} } -, { ":mailbox_with_mail:", "\u1f4eC", NULL, {NULL} } -, { ":mailbox_with_no_mail:", "\u1f4eD", NULL, {NULL} } -, { ":male-artist:", "\u1f468\u200d\u1f3a8", NULL, {NULL} } -, { ":male-astronaut:", "\u1f468\u200d\u1f680", NULL, {NULL} } -, { ":male-construction-worker:", "\u1f477\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male-cook:", "\u1f468\u200d\u1f373", NULL, {NULL} } -, { ":male-detective:", "\u1f575\ufe0f\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male-doctor:", "\u1f468\u200d\u2695\ufe0f", NULL, {NULL} } -, { ":male-factory-worker:", "\u1f468\u200d\u1f3eD", NULL, {NULL} } -, { ":male-farmer:", "\u1f468\u200d\u1f33E", NULL, {NULL} } -, { ":male-firefighter:", "\u1f468\u200d\u1f692", NULL, {NULL} } -, { ":male-guard:", "\u1f482\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male-judge:", "\u1f468\u200d\u2696\ufe0f", NULL, {NULL} } -, { ":male-mechanic:", "\u1f468\u200d\u1f527", NULL, {NULL} } -, { ":male-office-worker:", "\u1f468\u200d\u1f4bC", NULL, {NULL} } -, { ":male-pilot:", "\u1f468\u200d\u2708\ufe0f", NULL, {NULL} } -, { ":male-police-officer:", "\u1f46E\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male-scientist:", "\u1f468\u200d\u1f52C", NULL, {NULL} } -, { ":male-singer:", "\u1f468\u200d\u1f3a4", NULL, {NULL} } -, { ":male-student:", "\u1f468\u200d\u1f393", NULL, {NULL} } -, { ":male-teacher:", "\u1f468\u200d\u1f3eB", NULL, {NULL} } -, { ":male-technologist:", "\u1f468\u200d\u1f4bB", NULL, {NULL} } -, { ":male_elf:", "\u1f9dD\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male_fairy:", "\u1f9dA\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male_genie:", "\u1f9dE\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male_mage:", "\u1f9d9\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male_sign:", "\u2642\ufe0f", NULL, {NULL} } -, { ":male_vampire:", "\u1f9dB\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":male_zombie:", "\u1f9dF\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man:", "\u1f468", NULL, {NULL} } -, { ":man-biking:", "\u1f6b4\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-bouncing-ball:", "\u26f9\ufe0f\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-bowing:", "\u1f647\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-boy:", "\u1f468\u200d\u1f466", NULL, {NULL} } -, { ":man-boy-boy:", "\u1f468\u200d\u1f466\u200d\u1f466", NULL, {NULL} } -, { ":man-cartwheeling:", "\u1f938\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-facepalming:", "\u1f926\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-frowning:", "\u1f64D\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-gesturing-no:", "\u1f645\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-gesturing-ok:", "\u1f646\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-getting-haircut:", "\u1f487\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-getting-massage:", "\u1f486\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-girl:", "\u1f468\u200d\u1f467", NULL, {NULL} } -, { ":man-girl-boy:", "\u1f468\u200d\u1f467\u200d\u1f466", NULL, {NULL} } -, { ":man-girl-girl:", "\u1f468\u200d\u1f467\u200d\u1f467", NULL, {NULL} } -, { ":man-golfing:", "\u1f3cC\ufe0f\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-heart-man:", "\u1f468\u200d\u2764\ufe0f\u200d\u1f468", NULL, {NULL} } -, { ":man-juggling:", "\u1f939\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-kiss-man:", "\u1f468\u200d\u2764\ufe0f\u200d\u1f48B\u200d\u1f468", NULL, {NULL} } -, { ":man-lifting-weights:", "\u1f3cB\ufe0f\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-man-boy:", "\u1f468\u200d\u1f468\u200d\u1f466", NULL, {NULL} } -, { ":man-man-boy-boy:", "\u1f468\u200d\u1f468\u200d\u1f466\u200d\u1f466", NULL, {NULL} } -, { ":man-man-girl:", "\u1f468\u200d\u1f468\u200d\u1f467", NULL, {NULL} } -, { ":man-man-girl-boy:", "\u1f468\u200d\u1f468\u200d\u1f467\u200d\u1f466", NULL, {NULL} } -, { ":man-man-girl-girl:", "\u1f468\u200d\u1f468\u200d\u1f467\u200d\u1f467", NULL, {NULL} } -, { ":man-mountain-biking:", "\u1f6b5\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-playing-handball:", "\u1f93E\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-playing-water-polo:", "\u1f93D\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-pouting:", "\u1f64E\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-raising-hand:", "\u1f64B\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-rowing-boat:", "\u1f6a3\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-running:", "\u1f3c3\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-shrugging:", "\u1f937\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-surfing:", "\u1f3c4\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-swimming:", "\u1f3cA\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-tipping-hand:", "\u1f481\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-walking:", "\u1f6b6\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-wearing-turban:", "\u1f473\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-with-bunny-ears-partying:", "\u1f46F\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man-woman-boy:", "\u1f468\u200d\u1f469\u200d\u1f466", NULL, {NULL} } -, { ":man-woman-boy:", "\u1f46A", NULL, {NULL} } -, { ":man-woman-boy-boy:", "\u1f468\u200d\u1f469\u200d\u1f466\u200d\u1f466", NULL, {NULL} } -, { ":man-woman-girl:", "\u1f468\u200d\u1f469\u200d\u1f467", NULL, {NULL} } -, { ":man-woman-girl-boy:", "\u1f468\u200d\u1f469\u200d\u1f467\u200d\u1f466", NULL, {NULL} } -, { ":man-woman-girl-girl:", "\u1f468\u200d\u1f469\u200d\u1f467\u200d\u1f467", NULL, {NULL} } -, { ":man-wrestling:", "\u1f93C\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man_and_woman_holding_hands:", "\u1f46B", NULL, {NULL} } -, { ":man_climbing:", "\u1f9d7\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man_dancing:", "\u1f57A", NULL, {NULL} } -, { ":man_in_business_suit_levitating:", "\u1f574\ufe0f", NULL, {NULL} } -, { ":man_in_lotus_position:", "\u1f9d8\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man_in_steamy_room:", "\u1f9d6\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":man_in_tuxedo:", "\u1f935", NULL, {NULL} } -, { ":man_with_gua_pi_mao:", "\u1f472", NULL, {NULL} } -, { ":man_with_turban:", "\u1f473", NULL, {NULL} } -, { ":mans_shoe:", "\u1f45E", NULL, {NULL} } -, { ":mantelpiece_clock:", "\u1f570\ufe0f", NULL, {NULL} } -, { ":maple_leaf:", "\u1f341", NULL, {NULL} } -, { ":martial_arts_uniform:", "\u1f94B", NULL, {NULL} } -, { ":mask:", "\u1f637", NULL, {NULL} } -, { ":massage:", "\u1f486", NULL, {NULL} } -, { ":meat_on_bone:", "\u1f356", NULL, {NULL} } -, { ":medal:", "\u1f396\ufe0f", NULL, {NULL} } -, { ":medical_symbol:", "\u2695\ufe0f", NULL, {NULL} } -, { ":mega:", "\u1f4e3", NULL, {NULL} } -, { ":melon:", "\u1f348", NULL, {NULL} } -, { ":memo:", "\u1f4dD", NULL, {NULL} } -, { ":menorah_with_nine_branches:", "\u1f54E", NULL, {NULL} } -, { ":mens:", "\u1f6b9", NULL, {NULL} } -, { ":mermaid:", "\u1f9dC\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":merman:", "\u1f9dC\u200d\u2642\ufe0f", NULL, {NULL} } -, { ":merperson:", "\u1f9dC", NULL, {NULL} } -, { ":metro:", "\u1f687", NULL, {NULL} } -, { ":microphone:", "\u1f3a4", NULL, {NULL} } -, { ":microscope:", "\u1f52C", NULL, {NULL} } -, { ":middle_finger:", "\u1f595", NULL, {NULL} } -, { ":milky_way:", "\u1f30C", NULL, {NULL} } -, { ":minibus:", "\u1f690", NULL, {NULL} } -, { ":minidisc:", "\u1f4bD", NULL, {NULL} } -, { ":mobile_phone_off:", "\u1f4f4", NULL, {NULL} } -, { ":money_mouth_face:", "\u1f911", NULL, {NULL} } -, { ":money_with_wings:", "\u1f4b8", NULL, {NULL} } -, { ":moneybag:", "\u1f4b0", NULL, {NULL} } -, { ":monkey:", "\u1f412", NULL, {NULL} } -, { ":monkey_face:", "\u1f435", NULL, {":o)", NULL} } -, { ":monorail:", "\u1f69D", NULL, {NULL} } -, { ":moon:", "\u1f314", NULL, {NULL} } -, { ":mortar_board:", "\u1f393", NULL, {NULL} } -, { ":mosque:", "\u1f54C", NULL, {NULL} } -, { ":mostly_sunny:", "\u1f324\ufe0f", NULL, {NULL} } -, { ":mother_christmas:", "\u1f936", NULL, {NULL} } -, { ":motor_boat:", "\u1f6e5\ufe0f", NULL, {NULL} } -, { ":motor_scooter:", "\u1f6f5", NULL, {NULL} } -, { ":motorway:", "\u1f6e3\ufe0f", NULL, {NULL} } -, { ":mount_fuji:", "\u1f5fB", NULL, {NULL} } -, { ":mountain:", "\u26f0\ufe0f", NULL, {NULL} } -, { ":mountain_bicyclist:", "\u1f6b5", NULL, {NULL} } -, { ":mountain_cableway:", "\u1f6a0", NULL, {NULL} } -, { ":mountain_railway:", "\u1f69E", NULL, {NULL} } -, { ":mouse:", "\u1f42D", NULL, {NULL} } -, { ":mouse2:", "\u1f401", NULL, {NULL} } -, { ":movie_camera:", "\u1f3a5", NULL, {NULL} } -, { ":moyai:", "\u1f5fF", NULL, {NULL} } -, { ":mrs_claus:", "\u1f936", NULL, {NULL} } -, { ":muscle:", "\u1f4aA", NULL, {NULL} } -, { ":mushroom:", "\u1f344", NULL, {NULL} } -, { ":musical_keyboard:", "\u1f3b9", NULL, {NULL} } -, { ":musical_note:", "\u1f3b5", NULL, {NULL} } -, { ":musical_score:", "\u1f3bC", NULL, {NULL} } -, { ":mute:", "\u1f507", NULL, {NULL} } -, { ":nail_care:", "\u1f485", NULL, {NULL} } -, { ":name_badge:", "\u1f4dB", NULL, {NULL} } -, { ":national_park:", "\u1f3dE\ufe0f", NULL, {NULL} } -, { ":nauseated_face:", "\u1f922", NULL, {NULL} } -, { ":necktie:", "\u1f454", NULL, {NULL} } -, { ":negative_squared_cross_mark:", "\u274e", NULL, {NULL} } -, { ":nerd_face:", "\u1f913", NULL, {NULL} } -, { ":neutral_face:", "\u1f610", NULL, {":|", ":-|", NULL} } -, { ":new:", "\u1f195", NULL, {NULL} } -, { ":new_moon:", "\u1f311", NULL, {NULL} } -, { ":new_moon_with_face:", "\u1f31A", NULL, {NULL} } -, { ":newspaper:", "\u1f4f0", NULL, {NULL} } -, { ":ng:", "\u1f196", NULL, {NULL} } -, { ":night_with_stars:", "\u1f303", NULL, {NULL} } -, { ":nine:", "9\ufe0f\u20e3", NULL, {NULL} } -, { ":no_bell:", "\u1f515", NULL, {NULL} } -, { ":no_bicycles:", "\u1f6b3", NULL, {NULL} } -, { ":no_entry:", "\u26d4", NULL, {NULL} } -, { ":no_entry_sign:", "\u1f6aB", NULL, {NULL} } -, { ":no_good:", "\u1f645", NULL, {NULL} } -, { ":no_mobile_phones:", "\u1f4f5", NULL, {NULL} } -, { ":no_mouth:", "\u1f636", NULL, {NULL} } -, { ":no_pedestrians:", "\u1f6b7", NULL, {NULL} } -, { ":no_smoking:", "\u1f6aD", NULL, {NULL} } -, { ":non-potable_water:", "\u1f6b1", NULL, {NULL} } -, { ":nose:", "\u1f443", NULL, {NULL} } -, { ":notebook:", "\u1f4d3", NULL, {NULL} } -, { ":notebook_with_decorative_cover:", "\u1f4d4", NULL, {NULL} } -, { ":notes:", "\u1f3b6", NULL, {NULL} } -, { ":nut_and_bolt:", "\u1f529", NULL, {NULL} } -, { ":o:", "\u2b55", NULL, {NULL} } -, { ":o2:", "\u1f17E\ufe0f", NULL, {NULL} } -, { ":ocean:", "\u1f30A", NULL, {NULL} } -, { ":octagonal_sign:", "\u1f6d1", NULL, {NULL} } -, { ":octopus:", "\u1f419", NULL, {NULL} } -, { ":oden:", "\u1f362", NULL, {NULL} } -, { ":office:", "\u1f3e2", NULL, {NULL} } -, { ":oil_drum:", "\u1f6e2\ufe0f", NULL, {NULL} } -, { ":ok:", "\u1f197", NULL, {NULL} } -, { ":ok_hand:", "\u1f44C", NULL, {NULL} } -, { ":ok_woman:", "\u1f646", NULL, {NULL} } -, { ":old_key:", "\u1f5dD\ufe0f", NULL, {NULL} } -, { ":older_adult:", "\u1f9d3", NULL, {NULL} } -, { ":older_man:", "\u1f474", NULL, {NULL} } -, { ":older_woman:", "\u1f475", NULL, {NULL} } -, { ":om_symbol:", "\u1f549\ufe0f", NULL, {NULL} } -, { ":on:", "\u1f51B", NULL, {NULL} } -, { ":oncoming_automobile:", "\u1f698", NULL, {NULL} } -, { ":oncoming_bus:", "\u1f68D", NULL, {NULL} } -, { ":oncoming_police_car:", "\u1f694", NULL, {NULL} } -, { ":oncoming_taxi:", "\u1f696", NULL, {NULL} } -, { ":one:", "1\ufe0f\u20e3", NULL, {NULL} } -, { ":open_book:", "\u1f4d6", NULL, {NULL} } -, { ":open_file_folder:", "\u1f4c2", NULL, {NULL} } -, { ":open_hands:", "\u1f450", NULL, {NULL} } -, { ":open_mouth:", "\u1f62E", NULL, {":o", ":-o", ":O", ":-O", NULL} } -, { ":ophiuchus:", "\u26ce", NULL, {NULL} } -, { ":orange_book:", "\u1f4d9", NULL, {NULL} } -, { ":orange_heart:", "\u1f9e1", NULL, {NULL} } -, { ":orthodox_cross:", "\u2626\ufe0f", NULL, {NULL} } -, { ":outbox_tray:", "\u1f4e4", NULL, {NULL} } -, { ":owl:", "\u1f989", NULL, {NULL} } -, { ":ox:", "\u1f402", NULL, {NULL} } -, { ":package:", "\u1f4e6", NULL, {NULL} } -, { ":page_facing_up:", "\u1f4c4", NULL, {NULL} } -, { ":page_with_curl:", "\u1f4c3", NULL, {NULL} } -, { ":pager:", "\u1f4dF", NULL, {NULL} } -, { ":palm_tree:", "\u1f334", NULL, {NULL} } -, { ":palms_up_together:", "\u1f932", NULL, {NULL} } -, { ":pancakes:", "\u1f95E", NULL, {NULL} } -, { ":panda_face:", "\u1f43C", NULL, {NULL} } -, { ":paperclip:", "\u1f4cE", NULL, {NULL} } -, { ":parking:", "\u1f17F\ufe0f", NULL, {NULL} } -, { ":part_alternation_mark:", "\u303d\ufe0f", NULL, {NULL} } -, { ":partly_sunny:", "\u26c5", NULL, {NULL} } -, { ":partly_sunny_rain:", "\u1f326\ufe0f", NULL, {NULL} } -, { ":passenger_ship:", "\u1f6f3\ufe0f", NULL, {NULL} } -, { ":passport_control:", "\u1f6c2", NULL, {NULL} } -, { ":paw_prints:", "\u1f43E", NULL, {NULL} } -, { ":peace_symbol:", "\u262e\ufe0f", NULL, {NULL} } -, { ":peach:", "\u1f351", NULL, {NULL} } -, { ":peanuts:", "\u1f95C", NULL, {NULL} } -, { ":pear:", "\u1f350", NULL, {NULL} } -, { ":pencil:", "\u1f4dD", NULL, {NULL} } -, { ":pencil2:", "\u270f\ufe0f", NULL, {NULL} } -, { ":penguin:", "\u1f427", NULL, {NULL} } -, { ":pensive:", "\u1f614", NULL, {NULL} } -, { ":performing_arts:", "\u1f3aD", NULL, {NULL} } -, { ":persevere:", "\u1f623", NULL, {NULL} } -, { ":person_climbing:", "\u1f9d7", NULL, {NULL} } -, { ":person_doing_cartwheel:", "\u1f938", NULL, {NULL} } -, { ":person_frowning:", "\u1f64D", NULL, {NULL} } -, { ":person_in_lotus_position:", "\u1f9d8", NULL, {NULL} } -, { ":person_in_steamy_room:", "\u1f9d6", NULL, {NULL} } -, { ":person_with_ball:", "\u26f9\ufe0f", NULL, {NULL} } -, { ":person_with_blond_hair:", "\u1f471", NULL, {NULL} } -, { ":person_with_headscarf:", "\u1f9d5", NULL, {NULL} } -, { ":person_with_pouting_face:", "\u1f64E", NULL, {NULL} } -, { ":phone:", "\u260e\ufe0f", NULL, {NULL} } -, { ":pick:", "\u26cf\ufe0f", NULL, {NULL} } -, { ":pie:", "\u1f967", NULL, {NULL} } -, { ":pig:", "\u1f437", NULL, {NULL} } -, { ":pig2:", "\u1f416", NULL, {NULL} } -, { ":pig_nose:", "\u1f43D", NULL, {NULL} } -, { ":pill:", "\u1f48A", NULL, {NULL} } -, { ":pineapple:", "\u1f34D", NULL, {NULL} } -, { ":pisces:", "\u2653", NULL, {NULL} } -, { ":pizza:", "\u1f355", NULL, {NULL} } -, { ":place_of_worship:", "\u1f6d0", NULL, {NULL} } -, { ":point_down:", "\u1f447", NULL, {NULL} } -, { ":point_left:", "\u1f448", NULL, {NULL} } -, { ":point_right:", "\u1f449", NULL, {NULL} } -, { ":point_up:", "\u261d\ufe0f", NULL, {NULL} } -, { ":point_up_2:", "\u1f446", NULL, {NULL} } -, { ":police_car:", "\u1f693", NULL, {NULL} } -, { ":poodle:", "\u1f429", NULL, {NULL} } -, { ":poop:", "\u1f4a9", NULL, {NULL} } -, { ":popcorn:", "\u1f37F", NULL, {NULL} } -, { ":post_office:", "\u1f3e3", NULL, {NULL} } -, { ":postal_horn:", "\u1f4eF", NULL, {NULL} } -, { ":postbox:", "\u1f4eE", NULL, {NULL} } -, { ":potable_water:", "\u1f6b0", NULL, {NULL} } -, { ":potato:", "\u1f954", NULL, {NULL} } -, { ":pouch:", "\u1f45D", NULL, {NULL} } -, { ":poultry_leg:", "\u1f357", NULL, {NULL} } -, { ":pound:", "\u1f4b7", NULL, {NULL} } -, { ":pouting_cat:", "\u1f63E", NULL, {NULL} } -, { ":pray:", "\u1f64F", NULL, {NULL} } -, { ":prayer_beads:", "\u1f4fF", NULL, {NULL} } -, { ":pregnant_woman:", "\u1f930", NULL, {NULL} } -, { ":pretzel:", "\u1f968", NULL, {NULL} } -, { ":prince:", "\u1f934", NULL, {NULL} } -, { ":princess:", "\u1f478", NULL, {NULL} } -, { ":printer:", "\u1f5a8\ufe0f", NULL, {NULL} } -, { ":punch:", "\u1f44A", NULL, {NULL} } -, { ":purple_heart:", "\u1f49C", "<3", {NULL} } -, { ":purse:", "\u1f45B", NULL, {NULL} } -, { ":pushpin:", "\u1f4cC", NULL, {NULL} } -, { ":put_litter_in_its_place:", "\u1f6aE", NULL, {NULL} } -, { ":question:", "\u2753", NULL, {NULL} } -, { ":rabbit:", "\u1f430", NULL, {NULL} } -, { ":rabbit2:", "\u1f407", NULL, {NULL} } -, { ":racehorse:", "\u1f40E", NULL, {NULL} } -, { ":racing_car:", "\u1f3cE\ufe0f", NULL, {NULL} } -, { ":racing_motorcycle:", "\u1f3cD\ufe0f", NULL, {NULL} } -, { ":radio:", "\u1f4fB", NULL, {NULL} } -, { ":radio_button:", "\u1f518", NULL, {NULL} } -, { ":radioactive_sign:", "\u2622\ufe0f", NULL, {NULL} } -, { ":rage:", "\u1f621", NULL, {NULL} } -, { ":railway_car:", "\u1f683", NULL, {NULL} } -, { ":railway_track:", "\u1f6e4\ufe0f", NULL, {NULL} } -, { ":rain_cloud:", "\u1f327\ufe0f", NULL, {NULL} } -, { ":rainbow:", "\u1f308", NULL, {NULL} } -, { ":rainbow-flag:", "\u1f3f3\ufe0f\u200d\u1f308", NULL, {NULL} } -, { ":raised_back_of_hand:", "\u1f91A", NULL, {NULL} } -, { ":raised_hand:", "\u270b", NULL, {NULL} } -, { ":raised_hand_with_fingers_splayed:", "\u1f590\ufe0f", NULL, {NULL} } -, { ":raised_hands:", "\u1f64C", NULL, {NULL} } -, { ":raising_hand:", "\u1f64B", NULL, {NULL} } -, { ":ram:", "\u1f40F", NULL, {NULL} } -, { ":ramen:", "\u1f35C", NULL, {NULL} } -, { ":rat:", "\u1f400", NULL, {NULL} } -, { ":recycle:", "\u267b\ufe0f", NULL, {NULL} } -, { ":red_car:", "\u1f697", NULL, {NULL} } -, { ":red_circle:", "\u1f534", NULL, {NULL} } -, { ":registered:", "\u00ae\ufe0f", NULL, {NULL} } -, { ":relaxed:", "\u263a\ufe0f", NULL, {NULL} } -, { ":relieved:", "\u1f60C", NULL, {NULL} } -, { ":reminder_ribbon:", "\u1f397\ufe0f", NULL, {NULL} } -, { ":repeat:", "\u1f501", NULL, {NULL} } -, { ":repeat_one:", "\u1f502", NULL, {NULL} } -, { ":restroom:", "\u1f6bB", NULL, {NULL} } -, { ":reversed_hand_with_middle_finger_extended:", "\u1f595", NULL, {NULL} } -, { ":revolving_hearts:", "\u1f49E", NULL, {NULL} } -, { ":rewind:", "\u23ea", NULL, {NULL} } -, { ":rhinoceros:", "\u1f98F", NULL, {NULL} } -, { ":ribbon:", "\u1f380", NULL, {NULL} } -, { ":rice:", "\u1f35A", NULL, {NULL} } -, { ":rice_ball:", "\u1f359", NULL, {NULL} } -, { ":rice_cracker:", "\u1f358", NULL, {NULL} } -, { ":rice_scene:", "\u1f391", NULL, {NULL} } -, { ":right-facing_fist:", "\u1f91C", NULL, {NULL} } -, { ":right_anger_bubble:", "\u1f5eF\ufe0f", NULL, {NULL} } -, { ":ring:", "\u1f48D", NULL, {NULL} } -, { ":robot_face:", "\u1f916", NULL, {NULL} } -, { ":rocket:", "\u1f680", NULL, {NULL} } -, { ":rolled_up_newspaper:", "\u1f5dE\ufe0f", NULL, {NULL} } -, { ":roller_coaster:", "\u1f3a2", NULL, {NULL} } -, { ":rolling_on_the_floor_laughing:", "\u1f923", NULL, {NULL} } -, { ":rooster:", "\u1f413", NULL, {NULL} } -, { ":rose:", "\u1f339", NULL, {NULL} } -, { ":rosette:", "\u1f3f5\ufe0f", NULL, {NULL} } -, { ":rotating_light:", "\u1f6a8", NULL, {NULL} } -, { ":round_pushpin:", "\u1f4cD", NULL, {NULL} } -, { ":rowboat:", "\u1f6a3", NULL, {NULL} } -, { ":ru:", "\u1f1f7\u1f1fA", NULL, {NULL} } -, { ":rugby_football:", "\u1f3c9", NULL, {NULL} } -, { ":runner:", "\u1f3c3", NULL, {NULL} } -, { ":running:", "\u1f3c3", NULL, {NULL} } -, { ":running_shirt_with_sash:", "\u1f3bD", NULL, {NULL} } -, { ":sa:", "\u1f202\ufe0f", NULL, {NULL} } -, { ":sagittarius:", "\u2650", NULL, {NULL} } -, { ":sailboat:", "\u26f5", NULL, {NULL} } -, { ":sake:", "\u1f376", NULL, {NULL} } -, { ":sandal:", "\u1f461", NULL, {NULL} } -, { ":sandwich:", "\u1f96A", NULL, {NULL} } -, { ":santa:", "\u1f385", NULL, {NULL} } -, { ":satellite:", "\u1f6f0\ufe0f", NULL, {NULL} } -, { ":satellite_antenna:", "\u1f4e1", NULL, {NULL} } -, { ":satisfied:", "\u1f606", NULL, {":>", ":->", NULL} } -, { ":sauropod:", "\u1f995", NULL, {NULL} } -, { ":saxophone:", "\u1f3b7", NULL, {NULL} } -, { ":scales:", "\u2696\ufe0f", NULL, {NULL} } -, { ":scarf:", "\u1f9e3", NULL, {NULL} } -, { ":school:", "\u1f3eB", NULL, {NULL} } -, { ":school_satchel:", "\u1f392", NULL, {NULL} } -, { ":scissors:", "\u2702\ufe0f", NULL, {NULL} } -, { ":scooter:", "\u1f6f4", NULL, {NULL} } -, { ":scorpion:", "\u1f982", NULL, {NULL} } -, { ":scorpius:", "\u264f", NULL, {NULL} } -, { ":scream:", "\u1f631", NULL, {NULL} } -, { ":scream_cat:", "\u1f640", NULL, {NULL} } -, { ":scroll:", "\u1f4dC", NULL, {NULL} } -, { ":seat:", "\u1f4bA", NULL, {NULL} } -, { ":second_place_medal:", "\u1f948", NULL, {NULL} } -, { ":secret:", "\u3299\ufe0f", NULL, {NULL} } -, { ":see_no_evil:", "\u1f648", NULL, {NULL} } -, { ":seedling:", "\u1f331", NULL, {NULL} } -, { ":selfie:", "\u1f933", NULL, {NULL} } -, { ":serious_face_with_symbols_covering_mouth:", "\u1f92C", NULL, {NULL} } -, { ":seven:", "7\ufe0f\u20e3", NULL, {NULL} } -, { ":shallow_pan_of_food:", "\u1f958", NULL, {NULL} } -, { ":shamrock:", "\u2618\ufe0f", NULL, {NULL} } -, { ":shark:", "\u1f988", NULL, {NULL} } -, { ":shaved_ice:", "\u1f367", NULL, {NULL} } -, { ":sheep:", "\u1f411", NULL, {NULL} } -, { ":shell:", "\u1f41A", NULL, {NULL} } -, { ":shield:", "\u1f6e1\ufe0f", NULL, {NULL} } -, { ":shinto_shrine:", "\u26e9\ufe0f", NULL, {NULL} } -, { ":ship:", "\u1f6a2", NULL, {NULL} } -, { ":shirt:", "\u1f455", NULL, {NULL} } -, { ":shit:", "\u1f4a9", NULL, {NULL} } -, { ":shocked_face_with_exploding_head:", "\u1f92F", NULL, {NULL} } -, { ":shoe:", "\u1f45E", NULL, {NULL} } -, { ":shopping_bags:", "\u1f6cD\ufe0f", NULL, {NULL} } -, { ":shopping_trolley:", "\u1f6d2", NULL, {NULL} } -, { ":shower:", "\u1f6bF", NULL, {NULL} } -, { ":shrimp:", "\u1f990", NULL, {NULL} } -, { ":shrug:", "\u1f937", NULL, {NULL} } -, { ":shushing_face:", "\u1f92B", NULL, {NULL} } -, { ":sign_of_the_horns:", "\u1f918", NULL, {NULL} } -, { ":signal_strength:", "\u1f4f6", NULL, {NULL} } -, { ":six:", "6\ufe0f\u20e3", NULL, {NULL} } -, { ":six_pointed_star:", "\u1f52F", NULL, {NULL} } -, { ":ski:", "\u1f3bF", NULL, {NULL} } -, { ":skier:", "\u26f7\ufe0f", NULL, {NULL} } -, { ":skin-tone-2:", "\u1f3fB", NULL, {NULL} } -, { ":skin-tone-3:", "\u1f3fC", NULL, {NULL} } -, { ":skin-tone-4:", "\u1f3fD", NULL, {NULL} } -, { ":skin-tone-5:", "\u1f3fE", NULL, {NULL} } -, { ":skin-tone-6:", "\u1f3fF", NULL, {NULL} } -, { ":skull:", "\u1f480", NULL, {NULL} } -, { ":skull_and_crossbones:", "\u2620\ufe0f", NULL, {NULL} } -, { ":sled:", "\u1f6f7", NULL, {NULL} } -, { ":sleeping:", "\u1f634", NULL, {NULL} } -, { ":sleeping_accommodation:", "\u1f6cC", NULL, {NULL} } -, { ":sleepy:", "\u1f62A", NULL, {NULL} } -, { ":sleuth_or_spy:", "\u1f575\ufe0f", NULL, {NULL} } -, { ":slightly_frowning_face:", "\u1f641", NULL, {NULL} } -, { ":slightly_smiling_face:", "\u1f642", NULL, {":)", "(:", ":-)", NULL} } -, { ":slot_machine:", "\u1f3b0", NULL, {NULL} } -, { ":small_airplane:", "\u1f6e9\ufe0f", NULL, {NULL} } -, { ":small_blue_diamond:", "\u1f539", NULL, {NULL} } -, { ":small_orange_diamond:", "\u1f538", NULL, {NULL} } -, { ":small_red_triangle:", "\u1f53A", NULL, {NULL} } -, { ":small_red_triangle_down:", "\u1f53B", NULL, {NULL} } -, { ":smile:", "\u1f604", ":)", {"C:", "c:", ":D", ":-D", NULL} } -, { ":smile_cat:", "\u1f638", NULL, {NULL} } -, { ":smiley:", "\u1f603", ":)", {"=)", "=-)", NULL} } -, { ":smiley_cat:", "\u1f63A", NULL, {NULL} } -, { ":smiling_face_with_smiling_eyes_and_hand_covering_mouth:", "\u1f92D", NULL, {NULL} } -, { ":smiling_imp:", "\u1f608", NULL, {NULL} } -, { ":smirk:", "\u1f60F", NULL, {NULL} } -, { ":smirk_cat:", "\u1f63C", NULL, {NULL} } -, { ":smoking:", "\u1f6aC", NULL, {NULL} } -, { ":snail:", "\u1f40C", NULL, {NULL} } -, { ":snake:", "\u1f40D", NULL, {NULL} } -, { ":sneezing_face:", "\u1f927", NULL, {NULL} } -, { ":snow_capped_mountain:", "\u1f3d4\ufe0f", NULL, {NULL} } -, { ":snow_cloud:", "\u1f328\ufe0f", NULL, {NULL} } -, { ":snowboarder:", "\u1f3c2", NULL, {NULL} } -, { ":snowflake:", "\u2744\ufe0f", NULL, {NULL} } -, { ":snowman:", "\u2603\ufe0f", NULL, {NULL} } -, { ":snowman_without_snow:", "\u26c4", NULL, {NULL} } -, { ":sob:", "\u1f62D", ":'(", {NULL} } -, { ":soccer:", "\u26bd", NULL, {NULL} } -, { ":socks:", "\u1f9e6", NULL, {NULL} } -, { ":soon:", "\u1f51C", NULL, {NULL} } -, { ":sos:", "\u1f198", NULL, {NULL} } -, { ":sound:", "\u1f509", NULL, {NULL} } -, { ":space_invader:", "\u1f47E", NULL, {NULL} } -, { ":spades:", "\u2660\ufe0f", NULL, {NULL} } -, { ":spaghetti:", "\u1f35D", NULL, {NULL} } -, { ":sparkle:", "\u2747\ufe0f", NULL, {NULL} } -, { ":sparkler:", "\u1f387", NULL, {NULL} } -, { ":sparkles:", "\u2728", NULL, {NULL} } -, { ":sparkling_heart:", "\u1f496", NULL, {NULL} } -, { ":speak_no_evil:", "\u1f64A", NULL, {NULL} } -, { ":speaker:", "\u1f508", NULL, {NULL} } -, { ":speaking_head_in_silhouette:", "\u1f5e3\ufe0f", NULL, {NULL} } -, { ":speech_balloon:", "\u1f4aC", NULL, {NULL} } -, { ":speedboat:", "\u1f6a4", NULL, {NULL} } -, { ":spider:", "\u1f577\ufe0f", NULL, {NULL} } -, { ":spider_web:", "\u1f578\ufe0f", NULL, {NULL} } -, { ":spiral_calendar_pad:", "\u1f5d3\ufe0f", NULL, {NULL} } -, { ":spiral_note_pad:", "\u1f5d2\ufe0f", NULL, {NULL} } -, { ":spock-hand:", "\u1f596", NULL, {NULL} } -, { ":spoon:", "\u1f944", NULL, {NULL} } -, { ":sports_medal:", "\u1f3c5", NULL, {NULL} } -, { ":squid:", "\u1f991", NULL, {NULL} } -, { ":stadium:", "\u1f3dF\ufe0f", NULL, {NULL} } -, { ":staff_of_aesculapius:", "\u2695\ufe0f", NULL, {NULL} } -, { ":star:", "\u2b50", NULL, {NULL} } -, { ":star-struck:", "\u1f929", NULL, {NULL} } -, { ":star2:", "\u1f31F", NULL, {NULL} } -, { ":star_and_crescent:", "\u262a\ufe0f", NULL, {NULL} } -, { ":star_of_david:", "\u2721\ufe0f", NULL, {NULL} } -, { ":stars:", "\u1f320", NULL, {NULL} } -, { ":station:", "\u1f689", NULL, {NULL} } -, { ":statue_of_liberty:", "\u1f5fD", NULL, {NULL} } -, { ":steam_locomotive:", "\u1f682", NULL, {NULL} } -, { ":stew:", "\u1f372", NULL, {NULL} } -, { ":stopwatch:", "\u23f1\ufe0f", NULL, {NULL} } -, { ":straight_ruler:", "\u1f4cF", NULL, {NULL} } -, { ":strawberry:", "\u1f353", NULL, {NULL} } -, { ":stuck_out_tongue:", "\u1f61B", ":p", {":p", ":-p", ":P", ":-P", ":b", ":-b", NULL} } -, { ":stuck_out_tongue_closed_eyes:", "\u1f61D", NULL, {NULL} } -, { ":stuck_out_tongue_winking_eye:", "\u1f61C", ";p", {";p", ";-p", ";b", ";-b", ";P", ";-P", NULL} } -, { ":studio_microphone:", "\u1f399\ufe0f", NULL, {NULL} } -, { ":stuffed_flatbread:", "\u1f959", NULL, {NULL} } -, { ":sun_behind_cloud:", "\u1f325\ufe0f", NULL, {NULL} } -, { ":sun_behind_rain_cloud:", "\u1f326\ufe0f", NULL, {NULL} } -, { ":sun_small_cloud:", "\u1f324\ufe0f", NULL, {NULL} } -, { ":sun_with_face:", "\u1f31E", NULL, {NULL} } -, { ":sunflower:", "\u1f33B", NULL, {NULL} } -, { ":sunglasses:", "\u1f60E", NULL, {"8)", NULL} } -, { ":sunny:", "\u2600\ufe0f", NULL, {NULL} } -, { ":sunrise:", "\u1f305", NULL, {NULL} } -, { ":sunrise_over_mountains:", "\u1f304", NULL, {NULL} } -, { ":surfer:", "\u1f3c4", NULL, {NULL} } -, { ":sushi:", "\u1f363", NULL, {NULL} } -, { ":suspension_railway:", "\u1f69F", NULL, {NULL} } -, { ":sweat:", "\u1f613", NULL, {NULL} } -, { ":sweat_drops:", "\u1f4a6", NULL, {NULL} } -, { ":sweat_smile:", "\u1f605", NULL, {NULL} } -, { ":sweet_potato:", "\u1f360", NULL, {NULL} } -, { ":swimmer:", "\u1f3cA", NULL, {NULL} } -, { ":symbols:", "\u1f523", NULL, {NULL} } -, { ":synagogue:", "\u1f54D", NULL, {NULL} } -, { ":syringe:", "\u1f489", NULL, {NULL} } -, { ":t-rex:", "\u1f996", NULL, {NULL} } -, { ":table_tennis_paddle_and_ball:", "\u1f3d3", NULL, {NULL} } -, { ":taco:", "\u1f32E", NULL, {NULL} } -, { ":tada:", "\u1f389", NULL, {NULL} } -, { ":takeout_box:", "\u1f961", NULL, {NULL} } -, { ":tanabata_tree:", "\u1f38B", NULL, {NULL} } -, { ":tangerine:", "\u1f34A", NULL, {NULL} } -, { ":taurus:", "\u2649", NULL, {NULL} } -, { ":taxi:", "\u1f695", NULL, {NULL} } -, { ":tea:", "\u1f375", NULL, {NULL} } -, { ":telephone:", "\u260e\ufe0f", NULL, {NULL} } -, { ":telephone_receiver:", "\u1f4dE", NULL, {NULL} } -, { ":telescope:", "\u1f52D", NULL, {NULL} } -, { ":tennis:", "\u1f3bE", NULL, {NULL} } -, { ":tent:", "\u26fa", NULL, {NULL} } -, { ":the_horns:", "\u1f918", NULL, {NULL} } -, { ":thermometer:", "\u1f321\ufe0f", NULL, {NULL} } -, { ":thinking_face:", "\u1f914", NULL, {NULL} } -, { ":third_place_medal:", "\u1f949", NULL, {NULL} } -, { ":thought_balloon:", "\u1f4aD", NULL, {NULL} } -, { ":three:", "3\ufe0f\u20e3", NULL, {NULL} } -, { ":three_button_mouse:", "\u1f5b1\ufe0f", NULL, {NULL} } -, { ":thumbsdown:", "\u1f44E", NULL, {NULL} } -, { ":thumbsup:", "\u1f44D", NULL, {NULL} } -, { ":thunder_cloud_and_rain:", "\u26c8\ufe0f", NULL, {NULL} } -, { ":ticket:", "\u1f3aB", NULL, {NULL} } -, { ":tiger:", "\u1f42F", NULL, {NULL} } -, { ":tiger2:", "\u1f405", NULL, {NULL} } -, { ":timer_clock:", "\u23f2\ufe0f", NULL, {NULL} } -, { ":tired_face:", "\u1f62B", NULL, {NULL} } -, { ":tm:", "\u2122\ufe0f", NULL, {NULL} } -, { ":toilet:", "\u1f6bD", NULL, {NULL} } -, { ":tokyo_tower:", "\u1f5fC", NULL, {NULL} } -, { ":tomato:", "\u1f345", NULL, {NULL} } -, { ":tongue:", "\u1f445", NULL, {NULL} } -, { ":top:", "\u1f51D", NULL, {NULL} } -, { ":tophat:", "\u1f3a9", NULL, {NULL} } -, { ":tornado:", "\u1f32A\ufe0f", NULL, {NULL} } -, { ":tornado_cloud:", "\u1f32A\ufe0f", NULL, {NULL} } -, { ":trackball:", "\u1f5b2\ufe0f", NULL, {NULL} } -, { ":tractor:", "\u1f69C", NULL, {NULL} } -, { ":traffic_light:", "\u1f6a5", NULL, {NULL} } -, { ":train:", "\u1f68B", NULL, {NULL} } -, { ":train2:", "\u1f686", NULL, {NULL} } -, { ":tram:", "\u1f68A", NULL, {NULL} } -, { ":triangular_flag_on_post:", "\u1f6a9", NULL, {NULL} } -, { ":triangular_ruler:", "\u1f4d0", NULL, {NULL} } -, { ":trident:", "\u1f531", NULL, {NULL} } -, { ":triumph:", "\u1f624", NULL, {NULL} } -, { ":trolleybus:", "\u1f68E", NULL, {NULL} } -, { ":trophy:", "\u1f3c6", NULL, {NULL} } -, { ":tropical_drink:", "\u1f379", NULL, {NULL} } -, { ":tropical_fish:", "\u1f420", NULL, {NULL} } -, { ":truck:", "\u1f69A", NULL, {NULL} } -, { ":trumpet:", "\u1f3bA", NULL, {NULL} } -, { ":tshirt:", "\u1f455", NULL, {NULL} } -, { ":tulip:", "\u1f337", NULL, {NULL} } -, { ":tumbler_glass:", "\u1f943", NULL, {NULL} } -, { ":turkey:", "\u1f983", NULL, {NULL} } -, { ":turtle:", "\u1f422", NULL, {NULL} } -, { ":tv:", "\u1f4fA", NULL, {NULL} } -, { ":twisted_rightwards_arrows:", "\u1f500", NULL, {NULL} } -, { ":two:", "2\ufe0f\u20e3", NULL, {NULL} } -, { ":two_hearts:", "\u1f495", NULL, {NULL} } -, { ":two_men_holding_hands:", "\u1f46C", NULL, {NULL} } -, { ":two_women_holding_hands:", "\u1f46D", NULL, {NULL} } -, { ":u5272:", "\u1f239", NULL, {NULL} } -, { ":u5408:", "\u1f234", NULL, {NULL} } -, { ":u55b6:", "\u1f23A", NULL, {NULL} } -, { ":u6307:", "\u1f22F", NULL, {NULL} } -, { ":u6708:", "\u1f237\ufe0f", NULL, {NULL} } -, { ":u6709:", "\u1f236", NULL, {NULL} } -, { ":u6e80:", "\u1f235", NULL, {NULL} } -, { ":u7121:", "\u1f21A", NULL, {NULL} } -, { ":u7533:", "\u1f238", NULL, {NULL} } -, { ":u7981:", "\u1f232", NULL, {NULL} } -, { ":u7a7a:", "\u1f233", NULL, {NULL} } -, { ":uk:", "\u1f1eC\u1f1e7", NULL, {NULL} } -, { ":umbrella:", "\u2602\ufe0f", NULL, {NULL} } -, { ":umbrella_on_ground:", "\u26f1\ufe0f", NULL, {NULL} } -, { ":umbrella_with_rain_drops:", "\u2614", NULL, {NULL} } -, { ":unamused:", "\u1f612", ":(", {NULL} } -, { ":underage:", "\u1f51E", NULL, {NULL} } -, { ":unicorn_face:", "\u1f984", NULL, {NULL} } -, { ":unlock:", "\u1f513", NULL, {NULL} } -, { ":up:", "\u1f199", NULL, {NULL} } -, { ":upside_down_face:", "\u1f643", NULL, {NULL} } -, { ":us:", "\u1f1fA\u1f1f8", NULL, {NULL} } -, { ":v:", "\u270c\ufe0f", NULL, {NULL} } -, { ":vampire:", "\u1f9dB", NULL, {NULL} } -, { ":vertical_traffic_light:", "\u1f6a6", NULL, {NULL} } -, { ":vhs:", "\u1f4fC", NULL, {NULL} } -, { ":vibration_mode:", "\u1f4f3", NULL, {NULL} } -, { ":video_camera:", "\u1f4f9", NULL, {NULL} } -, { ":video_game:", "\u1f3aE", NULL, {NULL} } -, { ":violin:", "\u1f3bB", NULL, {NULL} } -, { ":virgo:", "\u264d", NULL, {NULL} } -, { ":volcano:", "\u1f30B", NULL, {NULL} } -, { ":volleyball:", "\u1f3d0", NULL, {NULL} } -, { ":vs:", "\u1f19A", NULL, {NULL} } -, { ":walking:", "\u1f6b6", NULL, {NULL} } -, { ":waning_crescent_moon:", "\u1f318", NULL, {NULL} } -, { ":waning_gibbous_moon:", "\u1f316", NULL, {NULL} } -, { ":warning:", "\u26a0\ufe0f", NULL, {NULL} } -, { ":wastebasket:", "\u1f5d1\ufe0f", NULL, {NULL} } -, { ":watch:", "\u231a", NULL, {NULL} } -, { ":water_buffalo:", "\u1f403", NULL, {NULL} } -, { ":water_polo:", "\u1f93D", NULL, {NULL} } -, { ":watermelon:", "\u1f349", NULL, {NULL} } -, { ":wave:", "\u1f44B", NULL, {NULL} } -, { ":waving_black_flag:", "\u1f3f4", NULL, {NULL} } -, { ":waving_white_flag:", "\u1f3f3\ufe0f", NULL, {NULL} } -, { ":wavy_dash:", "\u3030\ufe0f", NULL, {NULL} } -, { ":waxing_crescent_moon:", "\u1f312", NULL, {NULL} } -, { ":waxing_gibbous_moon:", "\u1f314", NULL, {NULL} } -, { ":wc:", "\u1f6bE", NULL, {NULL} } -, { ":weary:", "\u1f629", NULL, {NULL} } -, { ":wedding:", "\u1f492", NULL, {NULL} } -, { ":weight_lifter:", "\u1f3cB\ufe0f", NULL, {NULL} } -, { ":whale:", "\u1f433", NULL, {NULL} } -, { ":whale2:", "\u1f40B", NULL, {NULL} } -, { ":wheel_of_dharma:", "\u2638\ufe0f", NULL, {NULL} } -, { ":wheelchair:", "\u267f", NULL, {NULL} } -, { ":white_check_mark:", "\u2705", NULL, {NULL} } -, { ":white_circle:", "\u26aa", NULL, {NULL} } -, { ":white_flower:", "\u1f4aE", NULL, {NULL} } -, { ":white_frowning_face:", "\u2639\ufe0f", NULL, {NULL} } -, { ":white_large_square:", "\u2b1c", NULL, {NULL} } -, { ":white_medium_small_square:", "\u25fd", NULL, {NULL} } -, { ":white_medium_square:", "\u25fb\ufe0f", NULL, {NULL} } -, { ":white_small_square:", "\u25ab\ufe0f", NULL, {NULL} } -, { ":white_square_button:", "\u1f533", NULL, {NULL} } -, { ":wilted_flower:", "\u1f940", NULL, {NULL} } -, { ":wind_blowing_face:", "\u1f32C\ufe0f", NULL, {NULL} } -, { ":wind_chime:", "\u1f390", NULL, {NULL} } -, { ":wine_glass:", "\u1f377", NULL, {NULL} } -, { ":wink:", "\u1f609", ";)", {";)", ";-)", NULL} } -, { ":wolf:", "\u1f43A", NULL, {NULL} } -, { ":woman:", "\u1f469", NULL, {NULL} } -, { ":woman-biking:", "\u1f6b4\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-bouncing-ball:", "\u26f9\ufe0f\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-bowing:", "\u1f647\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-boy:", "\u1f469\u200d\u1f466", NULL, {NULL} } -, { ":woman-boy-boy:", "\u1f469\u200d\u1f466\u200d\u1f466", NULL, {NULL} } -, { ":woman-cartwheeling:", "\u1f938\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-facepalming:", "\u1f926\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-frowning:", "\u1f64D\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-gesturing-no:", "\u1f645\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-gesturing-ok:", "\u1f646\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-getting-haircut:", "\u1f487\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-getting-massage:", "\u1f486\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-girl:", "\u1f469\u200d\u1f467", NULL, {NULL} } -, { ":woman-girl-boy:", "\u1f469\u200d\u1f467\u200d\u1f466", NULL, {NULL} } -, { ":woman-girl-girl:", "\u1f469\u200d\u1f467\u200d\u1f467", NULL, {NULL} } -, { ":woman-golfing:", "\u1f3cC\ufe0f\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-heart-man:", "\u1f469\u200d\u2764\ufe0f\u200d\u1f468", NULL, {NULL} } -, { ":woman-heart-woman:", "\u1f469\u200d\u2764\ufe0f\u200d\u1f469", NULL, {NULL} } -, { ":woman-juggling:", "\u1f939\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-kiss-man:", "\u1f469\u200d\u2764\ufe0f\u200d\u1f48B\u200d\u1f468", NULL, {NULL} } -, { ":woman-kiss-woman:", "\u1f469\u200d\u2764\ufe0f\u200d\u1f48B\u200d\u1f469", NULL, {NULL} } -, { ":woman-lifting-weights:", "\u1f3cB\ufe0f\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-mountain-biking:", "\u1f6b5\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-playing-handball:", "\u1f93E\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-playing-water-polo:", "\u1f93D\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-pouting:", "\u1f64E\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-raising-hand:", "\u1f64B\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-rowing-boat:", "\u1f6a3\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-running:", "\u1f3c3\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-shrugging:", "\u1f937\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-surfing:", "\u1f3c4\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-swimming:", "\u1f3cA\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-tipping-hand:", "\u1f481\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-walking:", "\u1f6b6\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-wearing-turban:", "\u1f473\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-with-bunny-ears-partying:", "\u1f46F\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman-woman-boy:", "\u1f469\u200d\u1f469\u200d\u1f466", NULL, {NULL} } -, { ":woman-woman-boy-boy:", "\u1f469\u200d\u1f469\u200d\u1f466\u200d\u1f466", NULL, {NULL} } -, { ":woman-woman-girl:", "\u1f469\u200d\u1f469\u200d\u1f467", NULL, {NULL} } -, { ":woman-woman-girl-boy:", "\u1f469\u200d\u1f469\u200d\u1f467\u200d\u1f466", NULL, {NULL} } -, { ":woman-woman-girl-girl:", "\u1f469\u200d\u1f469\u200d\u1f467\u200d\u1f467", NULL, {NULL} } -, { ":woman-wrestling:", "\u1f93C\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman_climbing:", "\u1f9d7\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman_in_lotus_position:", "\u1f9d8\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":woman_in_steamy_room:", "\u1f9d6\u200d\u2640\ufe0f", NULL, {NULL} } -, { ":womans_clothes:", "\u1f45A", NULL, {NULL} } -, { ":womans_hat:", "\u1f452", NULL, {NULL} } -, { ":womens:", "\u1f6bA", NULL, {NULL} } -, { ":world_map:", "\u1f5fA\ufe0f", NULL, {NULL} } -, { ":worried:", "\u1f61F", NULL, {NULL} } -, { ":wrench:", "\u1f527", NULL, {NULL} } -, { ":wrestlers:", "\u1f93C", NULL, {NULL} } -, { ":writing_hand:", "\u270d\ufe0f", NULL, {NULL} } -, { ":x:", "\u274c", NULL, {NULL} } -, { ":yellow_heart:", "\u1f49B", "<3", {NULL} } -, { ":yen:", "\u1f4b4", NULL, {NULL} } -, { ":yin_yang:", "\u262f\ufe0f", NULL, {NULL} } -, { ":yum:", "\u1f60B", NULL, {NULL} } -, { ":zany_face:", "\u1f92A", NULL, {NULL} } -, { ":zap:", "\u26a1", NULL, {NULL} } -, { ":zebra_face:", "\u1f993", NULL, {NULL} } -, { ":zero:", "0\ufe0f\u20e3", NULL, {NULL} } -, { ":zipper_mouth_face:", "\u1f910", NULL, {NULL} } -, { ":zombie:", "\u1f9dF", NULL, {NULL} } -, { ":zzz:", "\u1f4a4", NULL, {NULL} } -}; - -static struct t_slack_emoji_by_text slack_emoji_by_text[] = -{ { "(:", "\u1f642", ":slightly_smiling_face:", {":slightly_smiling_face:", NULL} } -, { "):", "\u1f61E", ":disappointed:", {":disappointed:", NULL} } -, { "8)", "\u1f60E", ":sunglasses:", {":sunglasses:", NULL} } -, { ":'(", "\u1f622", ":cry:", {":cry:", NULL} } -, { ":(", "\u1f61E", ":disappointed:", {":disappointed:", NULL} } -, { ":)", "\u1f642", ":slightly_smiling_face:", {":slightly_smiling_face:", NULL} } -, { ":*", "\u1f618", ":kissing_heart:", {":kissing_heart:", NULL} } -, { ":-(", "\u1f61E", ":disappointed:", {":disappointed:", NULL} } -, { ":-)", "\u1f642", ":slightly_smiling_face:", {":slightly_smiling_face:", NULL} } -, { ":-*", "\u1f618", ":kissing_heart:", {":kissing_heart:", NULL} } -, { ":-/", "\u1f615", ":confused:", {":confused:", NULL} } -, { ":->", "\u1f606", ":laughing:", {":laughing:", ":satisfied:", NULL} } -, { ":-D", "\u1f604", ":smile:", {":smile:", NULL} } -, { ":-O", "\u1f62E", ":open_mouth:", {":open_mouth:", NULL} } -, { ":-P", "\u1f61B", ":stuck_out_tongue:", {":stuck_out_tongue:", NULL} } -, { ":-\\", "\u1f615", ":confused:", {":confused:", NULL} } -, { ":-b", "\u1f61B", ":stuck_out_tongue:", {":stuck_out_tongue:", NULL} } -, { ":-o", "\u1f62E", ":open_mouth:", {":open_mouth:", NULL} } -, { ":-p", "\u1f61B", ":stuck_out_tongue:", {":stuck_out_tongue:", NULL} } -, { ":-|", "\u1f610", ":neutral_face:", {":neutral_face:", NULL} } -, { ":/", "\u1f615", ":confused:", {":confused:", NULL} } -, { ":>", "\u1f606", ":laughing:", {":laughing:", ":satisfied:", NULL} } -, { ":D", "\u1f604", ":smile:", {":smile:", NULL} } -, { ":O", "\u1f62E", ":open_mouth:", {":open_mouth:", NULL} } -, { ":P", "\u1f61B", ":stuck_out_tongue:", {":stuck_out_tongue:", NULL} } -, { ":\\", "\u1f615", ":confused:", {":confused:", NULL} } -, { ":b", "\u1f61B", ":stuck_out_tongue:", {":stuck_out_tongue:", NULL} } -, { ":o", "\u1f62E", ":open_mouth:", {":open_mouth:", NULL} } -, { ":o)", "\u1f435", ":monkey_face:", {":monkey_face:", NULL} } -, { ":p", "\u1f61B", ":stuck_out_tongue:", {":stuck_out_tongue:", NULL} } -, { ":|", "\u1f610", ":neutral_face:", {":neutral_face:", NULL} } -, { ";)", "\u1f609", ":wink:", {":wink:", NULL} } -, { ";-)", "\u1f609", ":wink:", {":wink:", NULL} } -, { ";-P", "\u1f61C", ":stuck_out_tongue_winking_eye:", {":stuck_out_tongue_winking_eye:", NULL} } -, { ";-b", "\u1f61C", ":stuck_out_tongue_winking_eye:", {":stuck_out_tongue_winking_eye:", NULL} } -, { ";-p", "\u1f61C", ":stuck_out_tongue_winking_eye:", {":stuck_out_tongue_winking_eye:", NULL} } -, { ";P", "\u1f61C", ":stuck_out_tongue_winking_eye:", {":stuck_out_tongue_winking_eye:", NULL} } -, { ";b", "\u1f61C", ":stuck_out_tongue_winking_eye:", {":stuck_out_tongue_winking_eye:", NULL} } -, { ";p", "\u1f61C", ":stuck_out_tongue_winking_eye:", {":stuck_out_tongue_winking_eye:", NULL} } -, { ":(", "\u1f620", ":angry:", {":angry:", NULL} } -, { ">:-(", "\u1f620", ":angry:", {":angry:", NULL} } -, { "C:", "\u1f604", ":smile:", {":smile:", NULL} } -, { "D:", "\u1f627", ":anguished:", {":anguished:", NULL} } -, { "c:", "\u1f604", ":smile:", {":smile:", NULL} } -}; diff --git a/slack-input.c b/slack-input.c deleted file mode 100644 index 8643e8c..0000000 --- a/slack-input.c +++ /dev/null @@ -1,77 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-workspace.h" -#include "slack-channel.h" -#include "slack-buffer.h" -#include "slack-request.h" -#include "slack-message.h" -#include "slack-input.h" -#include "request/slack-request-chat-postmessage.h" - -int slack_input_data(struct t_gui_buffer *buffer, const char *input_data) -{ - struct t_slack_workspace *workspace = NULL; - struct t_slack_channel *channel = NULL; - struct t_slack_request *request; - char *text; - - slack_buffer_get_workspace_and_channel(buffer, &workspace, &channel); - - if (!workspace) - return WEECHAT_RC_ERROR; - - if (channel) - { - if (!workspace->is_connected) - { - weechat_printf(buffer, - _("%s%s: you are not connected to server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return WEECHAT_RC_OK; - } - - text = malloc(SLACK_MESSAGE_MAX_LENGTH); - if (!text) - { - weechat_printf(buffer, - _("%s%s: error allocating string"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return WEECHAT_RC_ERROR; - } - lws_urlencode(text, input_data, SLACK_MESSAGE_MAX_LENGTH); - - request = slack_request_chat_postmessage(workspace, - weechat_config_string( - workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]), - channel->id, text); - if (request) - slack_workspace_register_request(workspace, request); - - free(text); - } - else - { - weechat_printf(buffer, - _("%s%s: this buffer is not a channel!"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - } - - return WEECHAT_RC_OK; -} - -int slack_input_data_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *input_data) -{ - (void) pointer; - (void) data; - - return slack_input_data(buffer, input_data); -} diff --git a/slack-input.h b/slack-input.h deleted file mode 100644 index fbc1d59..0000000 --- a/slack-input.h +++ /dev/null @@ -1,12 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_INPUT_H_ -#define _SLACK_INPUT_H_ - -int slack_input_data_cb(const void *pointer, void *data, - struct t_gui_buffer *buffer, - const char *input_data); - -#endif /*SLACK_INPUT_H*/ diff --git a/slack-message.c b/slack-message.c deleted file mode 100644 index b7b1e3a..0000000 --- a/slack-message.c +++ /dev/null @@ -1,249 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include - -#include "../weechat-plugin.h" -#include "../slack.h" -#include "../slack-workspace.h" -#include "../slack-channel.h" -#include "../slack-user.h" -#include "../slack-message.h" - -static const char format_regex[] = "<([^>]*?)>"; -static const size_t max_groups = 2; - -char *slack_message_translate_code(struct t_slack_workspace *workspace, - const char *code) -{ - struct t_slack_channel *channel; - struct t_slack_user *user; - size_t resultlen; - char *identifier, *alttext, *result, *symbol, *prefix; - - identifier = strdup(code); - alttext = strchr(identifier, '|'); - if (alttext) - *alttext++ = '\0'; - - switch (identifier[0]) - { - case '#': /* channel */ - if (alttext) - { - prefix = "#"; - symbol = strdup(alttext); - } - else - { - channel = slack_channel_search(workspace, identifier+1); - if (channel) - { - prefix = "#"; - symbol = strdup(channel->name); - } - else - { - prefix = "Channel:"; - symbol = strdup(identifier+1); - } - } - break; - case '@': /* user */ - if (alttext) - { - prefix = "@"; - symbol = strdup(alttext); - } - else - { - user = slack_user_search(workspace, identifier+1); - if (user) - { - prefix = "@"; - symbol = strdup(user->profile.display_name); - } - else - { - prefix = "User:"; - symbol = strdup(identifier+1); - } - } - break; - case '!': /* special */ - if (alttext) - { - prefix = "@"; - symbol = strdup(alttext); - } - else - { - prefix = "@"; - symbol = strdup(identifier+1); - } - break; - default: /* url */ - prefix = ""; - symbol = strdup(code); - break; - } - - free(identifier); - resultlen = snprintf(NULL, 0, "%s%s%s%s", weechat_color("chat_nick"), prefix, symbol, weechat_color("reset")) + 1; - result = malloc(resultlen); - snprintf(result, resultlen, "%s%s%s%s", weechat_color("chat_nick"), prefix, symbol, weechat_color("reset")); - free(symbol); - - return result; -} - -void slack_message_htmldecode(char *dest, const char *src, size_t n) -{ - size_t i, j; - - for (i = 0, j = 0; i < n; i++, j++) - switch (src[i]) - { - case '\0': - dest[j] = '\0'; - return; - case '&': - if (src[i+1] == 'g' && - src[i+2] == 't' && - src[i+3] == ';') - { - dest[j] = '>'; - i += 3; - break; - } - else if (src[i+1] == 'l' && - src[i+2] == 't' && - src[i+3] == ';') - { - dest[j] = '<'; - i += 3; - break; - } - else if (src[i+1] == 'a' && - src[i+2] == 'm' && - src[i+3] == 'p' && - src[i+4] == ';') - { - dest[j] = '&'; - i += 4; - break; - } - /* fallthrough */ - default: - dest[j] = src[i]; - break; - } - dest[j-1] = '\0'; - return; -} - -char *slack_message_decode(struct t_slack_workspace *workspace, - const char *text) -{ - int rc; - regex_t reg; - regmatch_t groups[max_groups]; - char msgbuf[100]; - char *decoded_text; - const char *cursor; - size_t offset; - - if ((rc = regcomp(®, format_regex, REG_EXTENDED))) - { - regerror(rc, ®, msgbuf, sizeof(msgbuf)); - weechat_printf( - workspace->buffer, - _("%s%s: error compiling message formatting regex: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - msgbuf); - return strdup(text); - } - - decoded_text = malloc(SLACK_MESSAGE_MAX_LENGTH); - if (!decoded_text) - { - regfree(®); - weechat_printf( - workspace->buffer, - _("%s%s: error allocating space for message"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return strdup(text); - } - decoded_text[0] = '\0'; - - for (cursor = text; regexec(®, cursor, max_groups, groups, 0) == 0; cursor += offset) - { - offset = groups[0].rm_eo; - - char *copy = strdup(cursor); - if (!copy) - { - regfree(®); - free(decoded_text); - weechat_printf( - workspace->buffer, - _("%s%s: error allocating space for message"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return strdup(text); - } - copy[groups[1].rm_eo] = '\0'; - - char *match = strdup(copy + groups[1].rm_so); - if (!match) - { - free(copy); - regfree(®); - free(decoded_text); - weechat_printf( - workspace->buffer, - _("%s%s: error allocating space for message"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return strdup(text); - } - copy[groups[0].rm_so] = '\0'; - - char *prematch = strdup(copy); - if (!prematch) - { - free(match); - free(copy); - regfree(®); - free(decoded_text); - weechat_printf( - workspace->buffer, - _("%s%s: error allocating space for message"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return strdup(text); - } - free(copy); - - strncat(decoded_text, prematch, - SLACK_MESSAGE_MAX_LENGTH - strlen(decoded_text) - 1); - free(prematch); - - char *replacement = slack_message_translate_code(workspace, match); - free(match); - - strncat(decoded_text, replacement, - SLACK_MESSAGE_MAX_LENGTH - strlen(decoded_text) - 1); - free(replacement); - } - strncat(decoded_text, cursor, - SLACK_MESSAGE_MAX_LENGTH - strlen(decoded_text) - 1); - - slack_message_htmldecode(decoded_text, decoded_text, - SLACK_MESSAGE_MAX_LENGTH); - - regfree(®); - return decoded_text; -} diff --git a/slack-message.h b/slack-message.h deleted file mode 100644 index d223ba2..0000000 --- a/slack-message.h +++ /dev/null @@ -1,13 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_MESSAGE_H_ -#define _SLACK_MESSAGE_H_ - -#define SLACK_MESSAGE_MAX_LENGTH 40000 - -char *slack_message_decode(struct t_slack_workspace *workspace, - const char *text); - -#endif /*SLACK_MESSAGE_H*/ diff --git a/slack-oauth.c b/slack-oauth.c deleted file mode 100644 index be9f52d..0000000 --- a/slack-oauth.c +++ /dev/null @@ -1,245 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-oauth.h" - -static void (*weechat_callback)(char *token); - -static const char *const endpoint = "/api/oauth.access?" - "client_id=%s&client_secret=%s&code=%s"; -static char *uri; - -static int n = 0; -static struct lws *client_wsi = NULL; -static struct lws_context *context = NULL; - -static struct t_hook *slack_oauth_hook_timer = NULL; - -static inline int json_valid(json_object *object) -{ - if (!object) - { - weechat_printf( - NULL, - _("%s%s: error retrieving token: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return 0; - } - - return 1; -} - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - NULL, - _("%s%s: error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - in ? (char *)in : "(null)"); - client_wsi = NULL; - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - NULL, - _("%s%s: retrieving token... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - char *json_string = weechat_strndup(in, (int)len); - json_object *response, *ok, *error, *token; - - weechat_printf( - NULL, - _("%s%s: got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - token = json_object_object_get(response, "access_token"); - if (!json_valid(token)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - NULL, - _("%s%s: retrieved token: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - json_object_get_string(token)); - - weechat_callback(strdup(json_object_get_string(token))); - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - NULL, - _("%s%s: failed to retrieve token: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -int slack_oauth_timer_cb(const void *pointer, void *data, int remaining_calls) -{ - (void) pointer; - (void) data; - (void) remaining_calls; - - if (n >= 0 && client_wsi) - { - n = lws_service(context, 0); - } - else if (context) - { - lws_context_destroy(context); - context = NULL; - free(uri); - - if (slack_oauth_hook_timer) - weechat_unhook(slack_oauth_hook_timer); - } - - return WEECHAT_RC_OK; -} - -void slack_oauth_request_token(char *code, void (*callback)(char *token)) -{ - struct lws_context_creation_info info; - struct lws_client_connect_info i; - - if (client_wsi) - { - weechat_printf( - NULL, - _("%s%s: error: a registration is already in progress"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - - size_t urilen = snprintf(NULL, 0, endpoint, SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, code) + 1; - uri = malloc(urilen); - snprintf(uri, urilen, endpoint, SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, code); - - memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ - info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - info.protocols = protocols; - - context = lws_create_context(&info); - if (!context) - { - weechat_printf( - NULL, - _("%s%s: error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - else - { - weechat_printf( - NULL, - _("%s%s: contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME); - } - - memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */ - i.context = context; - i.ssl_connection = LCCSCF_USE_SSL; - i.port = 443; - i.address = "slack.com"; - i.path = uri; - i.host = i.address; - i.origin = i.address; - i.method = "GET"; - i.protocol = protocols[0].name; - i.pwsi = &client_wsi; - - lws_client_connect_via_info(&i); - - slack_oauth_hook_timer = weechat_hook_timer(1 * 1000, 0, 0, - &slack_oauth_timer_cb, - NULL, NULL); - - weechat_callback = callback; -} diff --git a/slack-oauth.h b/slack-oauth.h deleted file mode 100644 index d7a6538..0000000 --- a/slack-oauth.h +++ /dev/null @@ -1,10 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_OAUTH_H_ -#define _SLACK_OAUTH_H_ - -extern void slack_oauth_request_token(char *code, void (*callback)(char *token)); - -#endif /*SLACK_OAUTH_H*/ diff --git a/slack-request.c b/slack-request.c deleted file mode 100644 index 50c185e..0000000 --- a/slack-request.c +++ /dev/null @@ -1,27 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-workspace.h" -#include "slack-request.h" - -struct t_slack_request *slack_request_alloc( - struct t_slack_workspace *workspace) -{ - struct t_slack_request *request; - - request = malloc(sizeof(struct t_slack_request)); - memset(request, 0, sizeof(struct t_slack_request)); - - request->workspace = workspace; - request->idx = workspace->idx++; - - return request; -} diff --git a/slack-request.h b/slack-request.h deleted file mode 100644 index 675d947..0000000 --- a/slack-request.h +++ /dev/null @@ -1,29 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_REQUEST_H_ -#define _SLACK_REQUEST_H_ - -struct t_slack_request -{ - struct t_slack_workspace *workspace; - - int idx; - - const void *pointer; - void *data; - - char *uri; - struct lws *client_wsi; - struct lws_context *context; - struct t_json_chunk *json_chunks; - - struct t_slack_request *prev_request; - struct t_slack_request *next_request; -}; - -struct t_slack_request *slack_request_alloc( - struct t_slack_workspace *workspace); - -#endif /*SLACK_REQUEST_H*/ diff --git a/slack-teaminfo.c b/slack-teaminfo.c deleted file mode 100644 index 51ec2f7..0000000 --- a/slack-teaminfo.c +++ /dev/null @@ -1,348 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-teaminfo.h" - -static void (*weechat_callback)(struct t_slack_teaminfo *slack_teaminfo); - -static const char *const endpoint = "/api/team.info?" - "token=%s"; -static char *uri; - -static int n = 0; -static struct lws *client_wsi = NULL; -static struct lws_context *context = NULL; - -static struct t_hook *slack_teaminfo_hook_timer = NULL; - -struct t_json_chunk -{ - char *data; - struct t_json_chunk *next; -}; - -static struct t_json_chunk *slack_teaminfo_chunks = NULL; -static struct t_slack_teaminfo slack_teaminfo; - -static inline int json_valid(json_object *object) -{ - if (!object) - { - weechat_printf( - NULL, - _("%s%s: error retrieving workspace info: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return 0; - } - - return 1; -} - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - NULL, - _("%s%s: error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - in ? (char *)in : "(null)"); - client_wsi = NULL; - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - NULL, - _("%s%s: retrieving workspace details... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (slack_teaminfo_chunks) - { - for (last_chunk = slack_teaminfo_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - slack_teaminfo_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - json_object *response, *ok, *error, *team; - json_object *id, *name, *domain, *email_domain; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (slack_teaminfo_chunks) - { - chunk_count++; - for (chunk_ptr = slack_teaminfo_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = slack_teaminfo_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(slack_teaminfo_chunks->data); - free(slack_teaminfo_chunks); - slack_teaminfo_chunks = chunk_ptr; - } - - weechat_printf( - NULL, - _("%s%s: got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - team = json_object_object_get(response, "team"); - if (!json_valid(team)) - { - json_object_put(response); - free(json_string); - return 0; - } - - id = json_object_object_get(team, "id"); - if (!json_valid(id)) - { - json_object_put(response); - free(json_string); - return 0; - } - - name = json_object_object_get(team, "name"); - if (!json_valid(name)) - { - json_object_put(response); - free(json_string); - return 0; - } - - domain = json_object_object_get(team, "domain"); - if (!json_valid(domain)) - { - json_object_put(response); - free(json_string); - return 0; - } - - email_domain = json_object_object_get(team, "email_domain"); - if (!json_valid(email_domain)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - NULL, - _("%s%s: retrieved workspace details for %s@%s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - json_object_get_string(name), json_object_get_string(domain)); - - slack_teaminfo.id = json_object_get_string(id); - slack_teaminfo.name = json_object_get_string(name); - slack_teaminfo.domain = json_object_get_string(domain); - slack_teaminfo.email_domain = json_object_get_string(email_domain); - - weechat_callback(&slack_teaminfo); - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - NULL, - _("%s%s: failed to retrieve workspace details: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -int slack_teaminfo_timer_cb(const void *pointer, void *data, int remaining_calls) -{ - (void) pointer; - (void) data; - (void) remaining_calls; - - if (n >= 0 && client_wsi) - { - n = lws_service(context, 0); - } - else if (context) - { - lws_context_destroy(context); - context = NULL; - free(uri); - - if (slack_teaminfo_hook_timer) - weechat_unhook(slack_teaminfo_hook_timer); - } - - return WEECHAT_RC_OK; -} - -void slack_teaminfo_fetch(char *token, void (*callback)(struct t_slack_teaminfo *slack_teaminfo)) -{ - struct lws_context_creation_info info; - struct lws_client_connect_info i; - - if (client_wsi) - { - weechat_printf( - NULL, - _("%s%s: error: a registration is already in progress"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - - slack_teaminfo.token = strdup(token); - - size_t urilen = snprintf(NULL, 0, endpoint, token) + 1; - uri = malloc(urilen); - snprintf(uri, urilen, endpoint, token); - - memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ - info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - info.protocols = protocols; - - context = lws_create_context(&info); - if (!context) - { - weechat_printf( - NULL, - _("%s%s: error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - else - { - weechat_printf( - NULL, - _("%s%s: contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME); - } - - memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */ - i.context = context; - i.ssl_connection = LCCSCF_USE_SSL; - i.port = 443; - i.address = "slack.com"; - i.path = uri; - i.host = i.address; - i.origin = i.address; - i.method = "GET"; - i.protocol = protocols[0].name; - i.pwsi = &client_wsi; - - lws_client_connect_via_info(&i); - - slack_teaminfo_hook_timer = weechat_hook_timer(1 * 1000, 0, 0, - &slack_teaminfo_timer_cb, - NULL, NULL); - - weechat_callback = callback; -} - -void free_teaminfo(struct t_slack_teaminfo *teaminfo) -{ - free(teaminfo->token); -} diff --git a/slack-teaminfo.h b/slack-teaminfo.h deleted file mode 100644 index 67bd5d2..0000000 --- a/slack-teaminfo.h +++ /dev/null @@ -1,20 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_TEAMINFO_H_ -#define _SLACK_TEAMINFO_H_ - -struct t_slack_teaminfo -{ - const char *id; - const char *name; - const char *domain; - const char *email_domain; - char *token; -}; - -extern void slack_teaminfo_fetch(char *token, void (*callback)(struct t_slack_teaminfo *slack_teaminfo)); -extern void free_teaminfo(struct t_slack_teaminfo *teaminfo); - -#endif /*SLACK_TEAMINFO_H*/ diff --git a/slack-user.c b/slack-user.c deleted file mode 100644 index ff3fcd2..0000000 --- a/slack-user.c +++ /dev/null @@ -1,241 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-workspace.h" -#include "slack-user.h" -#include "slack-channel.h" - -const char *slack_user_get_colour(struct t_slack_user *user) -{ - return weechat_info_get("nick_color", user->profile.display_name); -} - -const char *slack_user_get_colour_for_nicklist(struct t_slack_user *user) -{ - return weechat_info_get("nick_color_name", user->profile.display_name); -} - -const char *slack_user_as_prefix(struct t_slack_workspace *workspace, - struct t_slack_user *user, - const char *name) -{ - static char result[256]; - - (void) workspace; - - snprintf(result, sizeof(result), "%s%s\t", - slack_user_get_colour(user), - name ? name : user->profile.display_name); - - return result; -} - -struct t_slack_user *slack_user_bot_search(struct t_slack_workspace *workspace, - const char *bot_id) -{ - struct t_slack_user *ptr_user; - - if (!workspace || !bot_id) - return NULL; - - for (ptr_user = workspace->users; ptr_user; - ptr_user = ptr_user->next_user) - { - if (ptr_user->profile.bot_id && - weechat_strcasecmp(ptr_user->profile.bot_id, bot_id) == 0) - return ptr_user; - } - - return NULL; -} - -struct t_slack_user *slack_user_search(struct t_slack_workspace *workspace, - const char *id) -{ - struct t_slack_user *ptr_user; - - if (!workspace || !id) - return NULL; - - for (ptr_user = workspace->users; ptr_user; - ptr_user = ptr_user->next_user) - { - if (weechat_strcasecmp(ptr_user->id, id) == 0) - return ptr_user; - } - - return NULL; -} - -void slack_user_nicklist_add(struct t_slack_workspace *workspace, - struct t_slack_channel *channel, - struct t_slack_user *user) -{ - struct t_gui_nick_group *ptr_group; - struct t_gui_buffer *ptr_buffer; - - ptr_buffer = channel ? channel->buffer : workspace->buffer; - - ptr_group = weechat_nicklist_search_group(ptr_buffer, NULL, - user->is_away ? - "+" : "..."); - weechat_nicklist_add_nick(ptr_buffer, ptr_group, - user->profile.display_name, - user->is_away ? - "weechat.color.nicklist_away" : - slack_user_get_colour_for_nicklist(user), - user->is_away ? "+" : "", - "bar_fg", - 1); -} - -struct t_slack_user *slack_user_new(struct t_slack_workspace *workspace, - const char *id, const char *display_name) -{ - struct t_slack_user *new_user, *ptr_user; - - if (!workspace || !id || !display_name) - { - return NULL; - } - - if (!display_name[0] && strcmp("USLACKBOT", id) == 0) - return NULL; - - if (!workspace->users) - slack_channel_add_nicklist_groups(workspace, NULL); - - ptr_user = slack_user_search(workspace, id); - if (ptr_user) - { - slack_user_nicklist_add(workspace, NULL, ptr_user); - return ptr_user; - } - - if ((new_user = malloc(sizeof(*new_user))) == NULL) - { - return NULL; - } - - new_user->prev_user = workspace->last_user; - new_user->next_user = NULL; - if (workspace->last_user) - (workspace->last_user)->next_user = new_user; - else - workspace->users = new_user; - workspace->last_user = new_user; - - new_user->id = strdup(id); - new_user->name = NULL; - new_user->team_id = NULL; - new_user->real_name = NULL; - new_user->colour = NULL; - new_user->deleted = 0; - - new_user->tz = NULL; - new_user->tz_label = NULL; - new_user->tz_offset = 0; - new_user->locale = NULL; - - new_user->profile.avatar_hash = NULL; - new_user->profile.status_text = NULL; - new_user->profile.status_emoji = NULL; - new_user->profile.real_name = NULL; - new_user->profile.display_name = display_name[0] ? - strdup(display_name) : - strdup("slackbot"); - new_user->profile.real_name_normalized = NULL; - new_user->profile.email = NULL; - new_user->profile.team = NULL; - new_user->profile.bot_id = NULL; - new_user->updated = 0; - new_user->is_away = 0; - - new_user->is_admin = 0; - new_user->is_owner = 0; - new_user->is_primary_owner = 0; - new_user->is_restricted = 0; - new_user->is_ultra_restricted = 0; - new_user->is_bot = 0; - new_user->is_stranger = 0; - new_user->is_app_user = 0; - new_user->has_2fa = 0; - - slack_user_nicklist_add(workspace, NULL, new_user); - - return new_user; -} - -void slack_user_free(struct t_slack_workspace *workspace, - struct t_slack_user *user) -{ - struct t_slack_user *new_users; - - if (!workspace || !user) - return; - - /* remove user from users list */ - if (workspace->last_user == user) - workspace->last_user = user->prev_user; - if (user->prev_user) - { - (user->prev_user)->next_user = user->next_user; - new_users = workspace->users; - } - else - new_users = user->next_user; - - if (user->next_user) - (user->next_user)->prev_user = user->prev_user; - - /* free user data */ - if (user->id) - free(user->id); - if (user->name) - free(user->name); - if (user->team_id) - free(user->team_id); - if (user->real_name) - free(user->real_name); - if (user->colour) - free(user->colour); - if (user->tz) - free(user->tz); - if (user->tz_label) - free(user->tz_label); - if (user->locale) - free(user->locale); - if (user->profile.avatar_hash) - free(user->profile.avatar_hash); - if (user->profile.status_text) - free(user->profile.status_text); - if (user->profile.status_emoji) - free(user->profile.status_emoji); - if (user->profile.real_name) - free(user->profile.real_name); - if (user->profile.display_name) - free(user->profile.display_name); - if (user->profile.real_name_normalized) - free(user->profile.real_name_normalized); - if (user->profile.email) - free(user->profile.email); - if (user->profile.team) - free(user->profile.team); - - free(user); - - workspace->users = new_users; -} - -void slack_user_free_all(struct t_slack_workspace *workspace) -{ - while (workspace->users) - slack_user_free(workspace, workspace->users); -} diff --git a/slack-user.h b/slack-user.h deleted file mode 100644 index cc97ec4..0000000 --- a/slack-user.h +++ /dev/null @@ -1,74 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_USER_H_ -#define _SLACK_USER_H_ - -struct t_slack_user_profile -{ - char *avatar_hash; - char *status_text; - char *status_emoji; - char *real_name; - char *display_name; - char *real_name_normalized; - char *email; - char *team; - char *bot_id; -}; - -struct t_slack_user -{ - char *id; - char *name; - char *team_id; - char *real_name; - char *colour; - - int deleted; - char *tz; - char *tz_label; - int tz_offset; - char *locale; - - struct t_slack_user_profile profile; - int updated; - int is_away; - - int is_admin; - int is_owner; - int is_primary_owner; - int is_restricted; - int is_ultra_restricted; - int is_bot; - int is_stranger; - int is_app_user; - int has_2fa; - - struct t_slack_user *prev_user; - struct t_slack_user *next_user; -}; - -const char *slack_user_get_colour(struct t_slack_user *user); - -const char *slack_user_as_prefix(struct t_slack_workspace *workspace, - struct t_slack_user *user, - const char *name); - -struct t_slack_user *slack_user_bot_search(struct t_slack_workspace *workspace, - const char *bot_id); - -struct t_slack_user *slack_user_search(struct t_slack_workspace *workspace, - const char *id); - -struct t_slack_user *slack_user_new(struct t_slack_workspace *workspace, - const char *id, const char *display_name); - -void slack_user_free_all(struct t_slack_workspace *workspace); - -void slack_user_nicklist_add(struct t_slack_workspace *workspace, - struct t_slack_channel *channel, - struct t_slack_user *user); - -#endif /*SLACK_USER_H*/ diff --git a/slack-workspace.c b/slack-workspace.c deleted file mode 100644 index 358cb24..0000000 --- a/slack-workspace.c +++ /dev/null @@ -1,972 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-config.h" -#include "slack-input.h" -#include "slack-workspace.h" -#include "slack-api.h" -#include "slack-request.h" -#include "slack-user.h" -#include "slack-channel.h" -#include "slack-buffer.h" - -struct t_slack_workspace *slack_workspaces = NULL; -struct t_slack_workspace *last_slack_workspace = NULL; - -char *slack_workspace_options[SLACK_WORKSPACE_NUM_OPTIONS][2] = -{ { "token", "" }, -}; - -static const char *const endpoint = "/api/rtm.connect?" - "token=%s&batch_presence_aware=true&presence_sub=false&"; - -static inline int json_valid(json_object *object, struct t_slack_workspace *workspace) -{ - if (!object) - { - weechat_printf( - workspace->buffer, - _("%s%s: error requesting websocket: unexpected response from server"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return 0; - } - - return 1; -} - -static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct t_slack_workspace *workspace = (struct t_slack_workspace *)user; - int status; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - workspace->buffer, - _("%s%s: error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - in ? (char *)in : "(null)"); - workspace->client_wsi = NULL; - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: - status = lws_http_client_http_response(wsi); - weechat_printf( - workspace->buffer, - _("%s%s: requesting a websocket... (%d)"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - status); - break; - - /* chunks of chunked content, with header removed */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - { - struct t_json_chunk *new_chunk, *last_chunk; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc((1024 * sizeof(char)) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (workspace->json_chunks) - { - for (last_chunk = workspace->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - workspace->json_chunks = new_chunk; - } - } - return 0; /* don't passthru */ - - /* uninterpreted http content */ - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - { - char buffer[1024 + LWS_PRE]; - char *px = buffer + LWS_PRE; - int lenx = sizeof(buffer) - LWS_PRE; - - if (lws_http_client_read(wsi, &px, &lenx) < 0) - return -1; - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: - { - int chunk_count, i; - char *json_string; - json_object *response, *ok, *error, *self, *team, *url; - json_object *id, *name, *domain; - struct t_json_chunk *chunk_ptr; - - chunk_count = 0; - if (workspace->json_chunks) - { - chunk_count++; - for (chunk_ptr = workspace->json_chunks; chunk_ptr->next; - chunk_ptr = chunk_ptr->next) - { - chunk_count++; - } - } - - json_string = malloc((1024 * sizeof(char) * chunk_count) + 1); - json_string[0] = '\0'; - - chunk_ptr = workspace->json_chunks; - for (i = 0; i < chunk_count; i++) - { - strncat(json_string, chunk_ptr->data, 1024); - chunk_ptr = chunk_ptr->next; - - free(workspace->json_chunks->data); - free(workspace->json_chunks); - workspace->json_chunks = chunk_ptr; - } - - weechat_printf( - workspace->buffer, - _("%s%s: got response: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - json_string); - - response = json_tokener_parse(json_string); - ok = json_object_object_get(response, "ok"); - if (!json_valid(ok, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - if(json_object_get_boolean(ok)) - { - self = json_object_object_get(response, "self"); - if (!json_valid(self, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - else - { - id = json_object_object_get(self, "id"); - if (!json_valid(id, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - workspace->user = strdup(json_object_get_string(id)); - - name = json_object_object_get(self, "name"); - if (!json_valid(name, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - workspace->nick = strdup(json_object_get_string(name)); - } - - team = json_object_object_get(response, "team"); - if (!json_valid(team, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - else - { - domain = json_object_object_get(team, "domain"); - if (!json_valid(domain, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - id = json_object_object_get(team, "id"); - if (!json_valid(id, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - workspace->id = strdup(json_object_get_string(id)); - - name = json_object_object_get(team, "name"); - if (!json_valid(name, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - workspace->name = strdup(json_object_get_string(name)); - } - - url = json_object_object_get(response, "url"); - if (!json_valid(url, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - workspace->ws_url = strdup(json_object_get_string(url)); - } - else - { - error = json_object_object_get(response, "error"); - if (!json_valid(error, workspace)) - { - json_object_put(response); - free(json_string); - return 0; - } - - weechat_printf( - workspace->buffer, - _("%s%s: failed to request websocket: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - json_object_get_string(error)); - } - - json_object_put(response); - free(json_string); - } - /* fallthrough */ - case LWS_CALLBACK_CLOSED_CLIENT_HTTP: - workspace->client_wsi = NULL; - /* Does not doing this cause a leak? - lws_cancel_service(lws_get_context(wsi));*/ /* abort poll wait */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "http", - callback_http, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -struct t_slack_workspace *slack_workspace_search(const char *workspace_domain) -{ - struct t_slack_workspace *ptr_workspace; - - if (!workspace_domain) - return NULL; - - for (ptr_workspace = slack_workspaces; ptr_workspace; - ptr_workspace = ptr_workspace->next_workspace) - { - if (strcmp(ptr_workspace->domain, workspace_domain) == 0) - return ptr_workspace; - } - - /* workspace not found */ - return NULL; -} - -struct t_slack_workspace *slack_workspace_casesearch (const char *workspace_domain) -{ - struct t_slack_workspace *ptr_workspace; - - if (!workspace_domain) - return NULL; - - for (ptr_workspace = slack_workspaces; ptr_workspace; - ptr_workspace = ptr_workspace->next_workspace) - { - if (weechat_strcasecmp (ptr_workspace->domain, workspace_domain) == 0) - return ptr_workspace; - } - - /* workspace not found */ - return NULL; -} - -int slack_workspace_search_option(const char *option_name) -{ - int i; - - if (!option_name) - return -1; - - for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++) - { - if (weechat_strcasecmp(slack_workspace_options[i][0], option_name) == 0) - return i; - } - - /* workspace option not found */ - return -1; -} - -struct t_slack_workspace *slack_workspace_alloc(const char *domain) -{ - struct t_slack_workspace *new_workspace; - int i, length; - char *option_name; - - if (slack_workspace_casesearch(domain)) - return NULL; - - /* alloc memory for new workspace */ - new_workspace = malloc(sizeof(*new_workspace)); - if (!new_workspace) - { - weechat_printf(NULL, - _("%s%s: error when allocating new workspace"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return NULL; - } - - /* add new workspace to queue */ - new_workspace->prev_workspace = last_slack_workspace; - new_workspace->next_workspace = NULL; - if (last_slack_workspace) - last_slack_workspace->next_workspace = new_workspace; - else - slack_workspaces = new_workspace; - last_slack_workspace = new_workspace; - - /* set properties */ - new_workspace->id = NULL; - new_workspace->name = NULL; - - /* set name */ - new_workspace->domain = strdup(domain); - - /* internal vars */ - new_workspace->reloading_from_config = 0; - new_workspace->reloaded_from_config = 0; - - new_workspace->is_connected = 0; - new_workspace->disconnected = 0; - - new_workspace->idx = 0; - new_workspace->uri = NULL; - new_workspace->ws_url = NULL; - new_workspace->client_wsi = NULL; - new_workspace->context = NULL; - new_workspace->json_chunks = NULL; - new_workspace->requests = NULL; - new_workspace->last_request = NULL; - - new_workspace->user = NULL; - new_workspace->nick = NULL; - - new_workspace->buffer = NULL; - new_workspace->buffer_as_string = NULL; - new_workspace->users = NULL; - new_workspace->last_user = NULL; - new_workspace->channels = NULL; - new_workspace->last_channel = NULL; - new_workspace->emoji = NULL; - new_workspace->last_emoji = NULL; - - /* create options with null value */ - for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++) - { - length = strlen(new_workspace->domain) + 1 + - strlen(slack_workspace_options[i][0]) + - 512 + /* inherited option name(slack.workspace_default.xxx) */ - 1; - option_name = malloc(length); - if (option_name) - { - snprintf(option_name, length, "%s.%s << slack.workspace_default.%s", - new_workspace->domain, - slack_workspace_options[i][0], - slack_workspace_options[i][0]); - new_workspace->options[i] = slack_config_workspace_new_option( - slack_config_file, - slack_config_section_workspace, - i, - option_name, - NULL, - NULL, - 1, - &slack_config_workspace_check_value_cb, - slack_workspace_options[i][0], - NULL, - &slack_config_workspace_change_cb, - slack_workspace_options[i][0], - NULL); - slack_config_workspace_change_cb(slack_workspace_options[i][0], NULL, - new_workspace->options[i]); - free(option_name); - } - } - - return new_workspace; -} - -void slack_workspace_free_data(struct t_slack_workspace *workspace) -{ - int i; - - if (!workspace) - return; - - /* free linked lists */ - /* - for (i = 0; i < IRC_SERVER_NUM_OUTQUEUES_PRIO; i++) - { - slack_workspace_outqueue_free_all(workspace, i); - } - slack_redirect_free_all(workspace); - slack_notify_free_all(workspace); - */ - slack_channel_free_all(workspace); - slack_user_free_all(workspace); - - /* free hashtables */ - /* - weechat_hashtable_free(workspace->join_manual); - weechat_hashtable_free(workspace->join_channel_key); - weechat_hashtable_free(workspace->join_noswitch); - */ - - /* free workspace data */ - for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++) - { - if (workspace->options[i]) - weechat_config_option_free(workspace->options[i]); - } - if (workspace->id) - free(workspace->id); - if (workspace->name) - free(workspace->name); - if (workspace->domain) - free(workspace->domain); - - if (workspace->uri) - free(workspace->uri); - if (workspace->ws_url) - free(workspace->ws_url); - if (workspace->context) - lws_context_destroy(workspace->context); - while (workspace->json_chunks) - { - struct t_json_chunk *chunk_ptr = workspace->json_chunks->next; - - free(workspace->json_chunks->data); - free(workspace->json_chunks); - workspace->json_chunks = chunk_ptr; - } - while (workspace->requests) - { - struct t_slack_request *request_ptr = workspace->requests->next_request; - - workspace->requests->client_wsi = NULL; - if (workspace->requests->context) - { - lws_context_destroy(workspace->requests->context); - workspace->requests->context = NULL; - if (workspace->requests->uri) - { - free(workspace->requests->uri); - workspace->requests->uri = NULL; - } - } - free(workspace->requests); - workspace->requests = request_ptr; - } - - if (workspace->user) - free(workspace->user); - if (workspace->nick) - free(workspace->nick); - - if (workspace->buffer_as_string) - free(workspace->buffer_as_string); - - slack_channel_free_all(workspace); - slack_user_free_all(workspace); -} - -void slack_workspace_free(struct t_slack_workspace *workspace) -{ - struct t_slack_workspace *new_slack_workspaces; - - if (!workspace) - return; - - /* - * close workspace buffer (and all channels/privates) - * (only if we are not in a /upgrade, because during upgrade we want to - * keep connections and closing workspace buffer would disconnect from workspace) - */ - if (workspace->buffer) - weechat_buffer_close(workspace->buffer); - - /* remove workspace from queue */ - if (last_slack_workspace == workspace) - last_slack_workspace = workspace->prev_workspace; - if (workspace->prev_workspace) - { - (workspace->prev_workspace)->next_workspace = workspace->next_workspace; - new_slack_workspaces = slack_workspaces; - } - else - new_slack_workspaces = workspace->next_workspace; - - if (workspace->next_workspace) - (workspace->next_workspace)->prev_workspace = workspace->prev_workspace; - - slack_workspace_free_data(workspace); - free(workspace); - slack_workspaces = new_slack_workspaces; -} - -void slack_workspace_free_all() -{ - /* for each workspace in memory, remove it */ - while (slack_workspaces) - { - slack_workspace_free(slack_workspaces); - } -} - -void slack_workspace_disconnect(struct t_slack_workspace *workspace, - int reconnect) -{ - (void) reconnect; - - struct t_slack_channel *ptr_channel; - (void) ptr_channel; - - if (workspace->is_connected) - { - /* - * remove all nicks and write disconnection message on each - * channel/private buffer - */ - slack_user_free_all(workspace); - weechat_nicklist_remove_all(workspace->buffer); - for (ptr_channel = workspace->channels; ptr_channel; - ptr_channel = ptr_channel->next_channel) - { - weechat_nicklist_remove_all(ptr_channel->buffer); - weechat_printf( - ptr_channel->buffer, - _("%s%s: disconnected from workspace"), - weechat_prefix("network"), SLACK_PLUGIN_NAME); - } - /* remove away status on workspace buffer */ - //weechat_buffer_set(workspace->buffer, "localvar_del_away", ""); - } - - slack_workspace_close_connection(workspace); - - if (workspace->buffer) - { - weechat_printf( - workspace->buffer, - _("%s%s: disconnected from workspace"), - weechat_prefix ("network"), SLACK_PLUGIN_NAME); - } - - /* - workspace->current_retry = 0; - - if (switch_address) - slack_workspace_switch_address(workspace, 0); - else - slack_workspace_set_index_current_address(workspace, 0); - - if (workspace->nick_modes) - { - free (workspace->nick_modes); - workspace->nick_modes = NULL; - weechat_bar_item_update ("input_prompt"); - weechat_bar_item_update ("slack_nick_modes"); - } - workspace->cap_away_notify = 0; - workspace->cap_account_notify = 0; - workspace->cap_extended_join = 0; - workspace->is_away = 0; - workspace->away_time = 0; - workspace->lag = 0; - workspace->lag_displayed = -1; - workspace->lag_check_time.tv_sec = 0; - workspace->lag_check_time.tv_usec = 0; - workspace->lag_next_check = time (NULL) + - weechat_config_integer (slack_config_network_lag_check); - workspace->lag_last_refresh = 0; - slack_workspace_set_lag (workspace); - workspace->monitor = 0; - workspace->monitor_time = 0; - - if (reconnect - && IRC_SERVER_OPTION_BOOLEAN(workspace, IRC_SERVER_OPTION_AUTORECONNECT)) - slack_workspace_reconnect_schedule(workspace); - else - { - workspace->reconnect_delay = 0; - workspace->reconnect_start = 0; - } - */ - - /* discard current nick if no reconnection asked */ - /* - if (!reconnect && workspace->nick) - slack_workspace_set_nick(workspace, NULL); - - slack_workspace_set_buffer_title(workspace); - - workspace->disconnected = 1; - */ - - /* send signal "slack_workspace_disconnected" with workspace name */ - /* - (void) weechat_hook_signal_send("slack_workspace_disconnected", - WEECHAT_HOOK_SIGNAL_STRING, workspace->name); - */ -} - -void slack_workspace_disconnect_all() -{ - struct t_slack_workspace *ptr_workspace; - - for (ptr_workspace = slack_workspaces; ptr_workspace; - ptr_workspace = ptr_workspace->next_workspace) - { - slack_workspace_disconnect(ptr_workspace, 0); - } -} - -struct t_gui_buffer *slack_workspace_create_buffer(struct t_slack_workspace *workspace) -{ - char buffer_name[256], charset_modifier[256]; - - snprintf(buffer_name, sizeof(buffer_name), - "workspace.%s", workspace->domain); - workspace->buffer = weechat_buffer_new(buffer_name, - &slack_input_data_cb, NULL, NULL, - &slack_buffer_close_cb, NULL, NULL); - if (!workspace->buffer) - return NULL; - - if (!weechat_buffer_get_integer(workspace->buffer, "short_name_is_set")) - weechat_buffer_set(workspace->buffer, "short_name", workspace->domain); - weechat_buffer_set(workspace->buffer, "localvar_set_type", "server"); - weechat_buffer_set(workspace->buffer, "localvar_set_server", workspace->domain); - weechat_buffer_set(workspace->buffer, "localvar_set_channel", workspace->domain); - snprintf(charset_modifier, sizeof (charset_modifier), - "workspace.%s", workspace->domain); - weechat_buffer_set(workspace->buffer, "localvar_set_charset_modifier", - charset_modifier); - weechat_buffer_set(workspace->buffer, "title", - (workspace->name) ? workspace->name : ""); - - weechat_buffer_set(workspace->buffer, "nicklist", "1"); - weechat_buffer_set(workspace->buffer, "nicklist_display_groups", "0"); - weechat_buffer_set_pointer(workspace->buffer, "nicklist_callback", - &slack_buffer_nickcmp_cb); - weechat_buffer_set_pointer(workspace->buffer, "nicklist_callback_pointer", - workspace); - - return workspace->buffer; -} - -void slack_workspace_close_connection(struct t_slack_workspace *workspace) -{ - struct t_slack_request *ptr_request; - - workspace->is_connected = 0; - workspace->client_wsi = NULL; - workspace->context = NULL; - - for (ptr_request = workspace->requests; ptr_request; - ptr_request = ptr_request->next_request) - { - if (ptr_request->context) - { - struct t_slack_request *new_requests; - - lws_context_destroy(ptr_request->context); - ptr_request->context = NULL; - if (ptr_request->uri) - { - free(ptr_request->uri); - ptr_request->uri = NULL; - } - - /* remove request from requests list */ - if (workspace->last_request == ptr_request) - workspace->last_request = ptr_request->prev_request; - if (ptr_request->prev_request) - { - (ptr_request->prev_request)->next_request = ptr_request->next_request; - new_requests = workspace->requests; - } - else - new_requests = ptr_request->next_request; - - if (ptr_request->next_request) - (ptr_request->next_request)->prev_request = ptr_request->prev_request; - - workspace->requests = new_requests; - } - } -} - -void slack_workspace_websocket_create(struct t_slack_workspace *workspace) -{ - struct lws_context_creation_info info; - struct lws_client_connect_info i; - const char *token; - - if (workspace->client_wsi) - { - weechat_printf( - workspace->buffer, - _("%s%s: error: a websocket already exists"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - - token = weechat_config_string(workspace->options[SLACK_WORKSPACE_OPTION_TOKEN]); - - size_t urilen = snprintf(NULL, 0, endpoint, token) + 1; - workspace->uri = malloc(urilen); - snprintf(workspace->uri, urilen, endpoint, token); - - memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ - info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ - info.protocols = protocols; - - workspace->context = lws_create_context(&info); - if (!workspace->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: contacting slack.com:443"), - weechat_prefix("network"), SLACK_PLUGIN_NAME); - } - - memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */ - i.context = workspace->context; - i.ssl_connection = LCCSCF_USE_SSL; - i.port = 443; - i.address = "slack.com"; - i.path = workspace->uri; - i.host = i.address; - i.origin = i.address; - i.method = "GET"; - i.protocol = protocols[0].name; - i.pwsi = &workspace->client_wsi; - i.userdata = workspace; - - lws_client_connect_via_info(&i); - - workspace->is_connected = 1; -} - -int slack_workspace_connect(struct t_slack_workspace *workspace) -{ - workspace->disconnected = 0; - - if (!workspace->buffer) - { - if (!slack_workspace_create_buffer(workspace)) - return 0; - weechat_buffer_set(workspace->buffer, "display", "auto"); - } - - slack_workspace_close_connection(workspace); - - slack_workspace_websocket_create(workspace); - - return 1; -} - -int slack_workspace_timer_cb(const void *pointer, void *data, int remaining_calls) -{ - struct t_slack_workspace *ptr_workspace; - struct t_slack_request *ptr_request; - - - (void) pointer; - (void) data; - (void) remaining_calls; - - for (ptr_workspace = slack_workspaces; ptr_workspace; - ptr_workspace = ptr_workspace->next_workspace) - { - if (!ptr_workspace->is_connected) - continue; - - for (ptr_request = ptr_workspace->requests; ptr_request; - ptr_request = ptr_request->next_request) - { - if (ptr_request->client_wsi) - { - lws_service(ptr_request->context, 0); - } - else if (ptr_request->context) - { - struct t_slack_request *new_requests; - - lws_context_destroy(ptr_request->context); - ptr_request->context = NULL; - if (ptr_request->uri) - { - free(ptr_request->uri); - ptr_request->uri = NULL; - } - ptr_request->pointer = NULL; - if (ptr_request->data) - { - free(ptr_request->data); - ptr_request->data = NULL; - } - - /* remove request from requests list */ - if (ptr_workspace->last_request == ptr_request) - ptr_workspace->last_request = ptr_request->prev_request; - if (ptr_request->prev_request) - { - (ptr_request->prev_request)->next_request = ptr_request->next_request; - new_requests = ptr_workspace->requests; - } - else - new_requests = ptr_request->next_request; - - if (ptr_request->next_request) - (ptr_request->next_request)->prev_request = ptr_request->prev_request; - - ptr_workspace->requests = new_requests; - } - } - - if (ptr_workspace->client_wsi) - { - lws_service(ptr_workspace->context, 0); - } - else if (ptr_workspace->context) - { - lws_context_destroy(ptr_workspace->context); - ptr_workspace->context = NULL; - if (ptr_workspace->uri) - { - free(ptr_workspace->uri); - ptr_workspace->uri = NULL; - } - if (ptr_workspace->ws_url) - { - slack_api_connect(ptr_workspace); - free(ptr_workspace->ws_url); - ptr_workspace->ws_url = NULL; - } - } - } - - return WEECHAT_RC_OK; -} - -void slack_workspace_register_request(struct t_slack_workspace *workspace, - struct t_slack_request *request) -{ - request->prev_request = workspace->last_request; - request->next_request = NULL; - if (workspace->last_request) - (workspace->last_request)->next_request = request; - else - workspace->requests = request; - workspace->last_request = request; -} - -struct t_slack_workspace_emoji *slack_workspace_emoji_search( - struct t_slack_workspace *workspace, - const char *name) -{ - struct t_slack_workspace_emoji *ptr_emoji; - - if (!workspace || !name) - return NULL; - - for (ptr_emoji = workspace->emoji; ptr_emoji; - ptr_emoji = ptr_emoji->next_emoji) - { - if (weechat_strcasecmp(ptr_emoji->name, name) == 0) - return ptr_emoji; - } - - return NULL; -} - -struct t_slack_workspace_emoji *slack_workspace_add_emoji( - struct t_slack_workspace *workspace, - const char *name, const char *url) -{ - struct t_slack_workspace_emoji *ptr_emoji, *new_emoji; - char shortname[SLACK_WORKSPACE_EMOJI_SHORTNAME_MAX_LEN + 1]; - - (void) url; - - if (!workspace || !name || !name[0]) - return NULL; - - snprintf(shortname, SLACK_WORKSPACE_EMOJI_SHORTNAME_MAX_LEN + 1, - ":%s:", name); - - ptr_emoji = slack_workspace_emoji_search(workspace, shortname); - if (ptr_emoji) - { - return ptr_emoji; - } - - if ((new_emoji = malloc(sizeof(*new_emoji))) == NULL) - return NULL; - - new_emoji->name = strdup(shortname); - new_emoji->url = strdup(url); - - new_emoji->prev_emoji = workspace->last_emoji; - new_emoji->next_emoji = NULL; - if (workspace->last_emoji) - (workspace->last_emoji)->next_emoji = new_emoji; - else - workspace->emoji = new_emoji; - workspace->last_emoji = new_emoji; - - return new_emoji; -} diff --git a/slack-workspace.h b/slack-workspace.h deleted file mode 100644 index 030b4ff..0000000 --- a/slack-workspace.h +++ /dev/null @@ -1,95 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, version 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef _SLACK_WORKSPACE_H_ -#define _SLACK_WORKSPACE_H_ - -#define SLACK_WORKSPACE_EMOJI_SHORTNAME_MAX_LEN 1 + 100 + 1 - -extern struct t_slack_workspace *slack_workspaces; -extern struct t_slack_workspace *last_slack_workspace; - -struct t_slack_workspace_emoji -{ - char *name; - char *url; - - struct t_slack_workspace_emoji *prev_emoji; - struct t_slack_workspace_emoji *next_emoji; -}; - -enum t_slack_workspace_option -{ - SLACK_WORKSPACE_OPTION_TOKEN, - SLACK_WORKSPACE_NUM_OPTIONS, -}; - -struct t_json_chunk -{ - char *data; - struct t_json_chunk *next; -}; - -struct t_slack_workspace -{ - char *id; - char *name; - char *domain; - struct t_config_option *options[SLACK_WORKSPACE_NUM_OPTIONS]; - - int reloading_from_config; - int reloaded_from_config; - - int is_connected; - int disconnected; - - int idx; - char *uri; - char *ws_url; - struct lws *client_wsi; - struct lws_context *context; - struct t_json_chunk *json_chunks; - struct t_slack_request *requests; - struct t_slack_request *last_request; - - char *user; - char *nick; - - struct t_gui_buffer *buffer; - char *buffer_as_string; - struct t_slack_user *users; - struct t_slack_user *last_user; - struct t_slack_channel *channels; - struct t_slack_channel *last_channel; - struct t_slack_workspace_emoji *emoji; - struct t_slack_workspace_emoji *last_emoji; - struct t_slack_workspace *prev_workspace; - struct t_slack_workspace *next_workspace; -}; - -extern char *slack_workspace_options[][2]; - -struct t_slack_workspace *slack_workspace_search(const char *workspace_domain); -struct t_slack_workspace *slack_workspace_casesearch (const char *workspace_domain); -int slack_workspace_search_option(const char *option_name); -struct t_slack_workspace *slack_workspace_alloc(const char *domain); -void slack_workspace_free_data(struct t_slack_workspace *workspace); -void slack_workspace_free(struct t_slack_workspace *workspace); -void slack_workspace_free_all(); -void slack_workspace_disconnect(struct t_slack_workspace *workspace, - int reconnect); -void slack_workspace_disconnect_all(); -void slack_workspace_close_connection(struct t_slack_workspace *workspace); -int slack_workspace_connect(struct t_slack_workspace *workspace); -int slack_workspace_timer_cb(const void *pointer, void *data, int remaining_calls); -void slack_workspace_register_request(struct t_slack_workspace *workspace, - struct t_slack_request *request); -struct t_slack_workspace_emoji *slack_workspace_emoji_search( - struct t_slack_workspace *workspace, - const char *name); -struct t_slack_workspace_emoji *slack_workspace_add_emoji( - struct t_slack_workspace *workspace, - const char *name, const char *url); - -#endif /*SLACK_WORKSPACE_H*/