source: protocols/bee_chat.c @ 356e2dd

Last change on this file since 356e2dd was 830864d, checked in by dequis <dx@…>, at 2015-03-15T09:31:18Z

WIP placeholder channels with hipchat implementation

i was going to clean this up and split in two commits but uhhh...
maybe some other day, i'm tired now

not very tested and i'm not 100% happy about the design, but sucks way
less than what i had in the hip-cat branch

feedback still appreciated.

this adds channels to the channel list without creating groupchats for
them, allowing users to /join them. what the hip-cat branch did before
but with proper api and hopefully less dumb behavior

it still 'leaks' them intentionally, just like it did before, but now it
prevents saving them to the xml so yay

also slightly improved channel name generation, refactored
bee_irc_chat_name_hint into three or four functions, and so on

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* Stuff to handle rooms                                                */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
23  Fifth Floor, Boston, MA  02110-1301  USA
24*/
25
26#define BITLBEE_CORE
27#include "bitlbee.h"
28
29struct groupchat *imcb_chat_new(struct im_connection *ic, const char *handle)
30{
31        struct groupchat *c = g_new0(struct groupchat, 1);
32        bee_t *bee = ic->bee;
33
34        /* This one just creates the conversation structure, user won't see
35           anything yet until s/he is joined to the conversation. (This
36           allows you to add other already present participants first.) */
37
38        ic->groupchats = g_slist_prepend(ic->groupchats, c);
39        c->ic = ic;
40        c->title = g_strdup(handle);
41        c->topic = g_strdup_printf(
42                "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!",
43                c->title);
44
45        if (set_getbool(&ic->bee->set, "debug")) {
46                imcb_log(ic, "Creating new conversation: (id=%p,handle=%s)", c, handle);
47        }
48
49        if (bee->ui->chat_new) {
50                bee->ui->chat_new(bee, c);
51        }
52
53        return c;
54}
55
56void imcb_chat_placeholder_new(struct im_connection *ic, const char *handle, const char *name, const char *topic)
57{
58        bee_t *bee = ic->bee;
59
60        if (bee->ui->chat_placeholder_new) {
61                bee->ui->chat_placeholder_new(bee, ic, handle, name, topic);
62        }
63}
64
65void imcb_chat_name_hint(struct groupchat *c, const char *name)
66{
67        bee_t *bee = c->ic->bee;
68
69        if (bee->ui->chat_name_hint) {
70                bee->ui->chat_name_hint(bee, c, name);
71        }
72}
73
74void imcb_chat_free(struct groupchat *c)
75{
76        struct im_connection *ic = c->ic;
77        bee_t *bee = ic->bee;
78        GList *ir;
79
80        if (bee->ui->chat_free) {
81                bee->ui->chat_free(bee, c);
82        }
83
84        if (set_getbool(&ic->bee->set, "debug")) {
85                imcb_log(ic, "You were removed from conversation %p", c);
86        }
87
88        ic->groupchats = g_slist_remove(ic->groupchats, c);
89
90        for (ir = c->in_room; ir; ir = ir->next) {
91                g_free(ir->data);
92        }
93        g_list_free(c->in_room);
94        g_free(c->title);
95        g_free(c->topic);
96        g_free(c);
97}
98
99static gboolean handle_is_self(struct im_connection *ic, const char *handle)
100{
101        return (ic->acc->prpl->handle_is_self) ?
102               ic->acc->prpl->handle_is_self(ic, handle) :
103               (ic->acc->prpl->handle_cmp(ic->acc->user, handle) == 0);
104}
105
106void imcb_chat_msg(struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at)
107{
108        struct im_connection *ic = c->ic;
109        bee_t *bee = ic->bee;
110        bee_user_t *bu;
111        gboolean temp;
112        char *s;
113
114        /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */
115        if (handle_is_self(ic, who)) {
116                return;
117        }
118
119        bu = bee_user_by_handle(bee, ic, who);
120        temp = (bu == NULL);
121
122        if (temp) {
123                bu = bee_user_new(bee, ic, who, BEE_USER_ONLINE);
124        }
125
126        s = set_getstr(&ic->bee->set, "strip_html");
127        if ((g_strcasecmp(s, "always") == 0) ||
128            ((ic->flags & OPT_DOES_HTML) && s)) {
129                strip_html(msg);
130        }
131
132        if (bee->ui->chat_msg) {
133                bee->ui->chat_msg(bee, c, bu, msg, sent_at);
134        }
135
136        if (temp) {
137                bee_user_free(bee, bu);
138        }
139}
140
141void imcb_chat_log(struct groupchat *c, char *format, ...)
142{
143        struct im_connection *ic = c->ic;
144        bee_t *bee = ic->bee;
145        va_list params;
146        char *text;
147
148        if (!bee->ui->chat_log) {
149                return;
150        }
151
152        va_start(params, format);
153        text = g_strdup_vprintf(format, params);
154        va_end(params);
155
156        bee->ui->chat_log(bee, c, text);
157        g_free(text);
158}
159
160void imcb_chat_topic(struct groupchat *c, char *who, char *topic, time_t set_at)
161{
162        struct im_connection *ic = c->ic;
163        bee_t *bee = ic->bee;
164        bee_user_t *bu;
165
166        if (!bee->ui->chat_topic) {
167                return;
168        }
169
170        if (who == NULL) {
171                bu = NULL;
172        } else if (handle_is_self(ic, who)) {
173                bu = bee->user;
174        } else {
175                bu = bee_user_by_handle(bee, ic, who);
176        }
177
178        if ((g_strcasecmp(set_getstr(&ic->bee->set, "strip_html"), "always") == 0) ||
179            ((ic->flags & OPT_DOES_HTML) && set_getbool(&ic->bee->set, "strip_html"))) {
180                strip_html(topic);
181        }
182
183        bee->ui->chat_topic(bee, c, topic, bu);
184}
185
186void imcb_chat_add_buddy(struct groupchat *c, const char *handle)
187{
188        struct im_connection *ic = c->ic;
189        bee_t *bee = ic->bee;
190        bee_user_t *bu = bee_user_by_handle(bee, ic, handle);
191        gboolean me;
192
193        if (set_getbool(&c->ic->bee->set, "debug")) {
194                imcb_log(c->ic, "User %s added to conversation %p", handle, c);
195        }
196
197        me = handle_is_self(ic, handle);
198
199        /* Most protocols allow people to join, even when they're not in
200           your contact list. Try to handle that here */
201        if (!me && !bu) {
202                bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL);
203        }
204
205        /* Add the handle to the room userlist */
206        /* TODO: Use bu instead of a string */
207        c->in_room = g_list_append(c->in_room, g_strdup(handle));
208
209        if (bee->ui->chat_add_user) {
210                bee->ui->chat_add_user(bee, c, me ? bee->user : bu);
211        }
212
213        if (me) {
214                c->joined = 1;
215        }
216}
217
218void imcb_chat_remove_buddy(struct groupchat *c, const char *handle, const char *reason)
219{
220        struct im_connection *ic = c->ic;
221        bee_t *bee = ic->bee;
222        bee_user_t *bu = NULL;
223
224        if (set_getbool(&bee->set, "debug")) {
225                imcb_log(ic, "User %s removed from conversation %p (%s)", handle, c, reason ? reason : "");
226        }
227
228        /* It might be yourself! */
229        if (handle_is_self(ic, handle)) {
230                if (c->joined == 0) {
231                        return;
232                }
233
234                bu = bee->user;
235                c->joined = 0;
236        } else {
237                bu = bee_user_by_handle(bee, ic, handle);
238        }
239
240        if (bee->ui->chat_remove_user && bu) {
241                bee->ui->chat_remove_user(bee, c, bu);
242        }
243}
244
245int bee_chat_msg(bee_t *bee, struct groupchat *c, const char *msg, int flags)
246{
247        struct im_connection *ic = c->ic;
248        char *buf = NULL;
249
250        if ((ic->flags & OPT_DOES_HTML) && (g_strncasecmp(msg, "<html>", 6) != 0)) {
251                buf = escape_html(msg);
252                msg = buf;
253        } else {
254                buf = g_strdup(msg);
255        }
256
257        ic->acc->prpl->chat_msg(c, buf, flags);
258        g_free(buf);
259
260        return 1;
261}
262
263struct groupchat *bee_chat_by_title(bee_t *bee, struct im_connection *ic, const char *title)
264{
265        struct groupchat *c;
266        GSList *l;
267
268        for (l = ic->groupchats; l; l = l->next) {
269                c = l->data;
270                if (strcmp(c->title, title) == 0) {
271                        return c;
272                }
273        }
274
275        return NULL;
276}
277
278void imcb_chat_invite(struct im_connection *ic, const char *name, const char *who, const char *msg)
279{
280        bee_user_t *bu = bee_user_by_handle(ic->bee, ic, who);
281
282        if (bu && ic->bee->ui->chat_invite) {
283                ic->bee->ui->chat_invite(ic->bee, bu, name, msg);
284        }
285}
Note: See TracBrowser for help on using the repository browser.