lastmsg/lastmsg.c
changeset 10 14f4f6dcc75a
child 11 573a48de8ee1
equal deleted inserted replaced
9:3a4ddded06f2 10:14f4f6dcc75a
       
     1 /*
       
     2    Copyright 2010 Mikael Berthe
       
     3 
       
     4   Module "lastmsg"    -- adds a /lastmsg command
       
     5                          Displays last personal messages
       
     6 
       
     7   This modules stores messages received in a MUC room while
       
     8   you are away (or not available) if they contain your nickname.
       
     9   When you're back, you can display them in the status window with
       
    10   the /lastmsg command.
       
    11   Note that this module is dumb: if your nick is foo and somebody
       
    12   says "foobar" the message will be stored!
       
    13 
       
    14 This module is free software: you can redistribute it and/or modify
       
    15 it under the terms of the GNU General Public License as published by
       
    16 the Free Software Foundation, either version 2 of the License, or
       
    17 (at your option) any later version.
       
    18 
       
    19 This program is distributed in the hope that it will be useful,
       
    20 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    22 GNU General Public License for more details.
       
    23 
       
    24 You should have received a copy of the GNU General Public License
       
    25 along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    26 */
       
    27 
       
    28 #include <mcabber/modules.h>
       
    29 #include <mcabber/commands.h>
       
    30 #include <mcabber/hooks.h>
       
    31 #include <mcabber/xmpp.h>
       
    32 #include <mcabber/logprint.h>
       
    33 
       
    34 static void lastmsg_init(void);
       
    35 static void lastmsg_uninit(void);
       
    36 
       
    37 /* Module description */
       
    38 module_info_t info_lastmsg = {
       
    39         .branch         = MCABBER_BRANCH,
       
    40         .api            = MCABBER_API_VERSION,
       
    41         .version        = "0.01",
       
    42         .description    = "Add a command /lastmsg",
       
    43         .requires       = NULL,
       
    44         .init           = lastmsg_init,
       
    45         .uninit         = lastmsg_uninit,
       
    46         .next           = NULL,
       
    47 };
       
    48 
       
    49 static GSList *lastmsg_list;
       
    50 
       
    51 struct lastm_T {
       
    52     gchar *mucname;
       
    53     gchar *nickname;
       
    54     gchar *msg;
       
    55 };
       
    56 
       
    57 static void do_lastmsg(char *args)
       
    58 {
       
    59   if (!lastmsg_list) {
       
    60     scr_log_print(LPRINT_NORMAL, "You have no new message.");
       
    61     return;
       
    62   }
       
    63 
       
    64   for (GSList *li = lastmsg_list; li ; li = g_slist_next(li)) {
       
    65     struct lastm_T *lastm_item = li->data;
       
    66     scr_LogPrint(LPRINT_NORMAL, "In <#%s>, \"%s\" said:\n%s",
       
    67                  lastm_item->mucname, lastm_item->nickname,
       
    68                  lastm_item->msg);
       
    69     g_free(lastm_item->mucname);
       
    70     g_free(lastm_item->nickname);
       
    71     g_free(lastm_item->msg);
       
    72   }
       
    73   g_slist_free(lastmsg_list);
       
    74   lastmsg_list = NULL;
       
    75 }
       
    76 
       
    77 static void last_message_hh(guint32 hid, hk_arg_t *args, gpointer userdata)
       
    78 {
       
    79   enum imstatus status;
       
    80   const gchar *bjid, *res, *msg;
       
    81   gboolean muc = FALSE;
       
    82 
       
    83   status = xmpp_getstatus();
       
    84 
       
    85   if (status != notavail && status != away)
       
    86     return;
       
    87 
       
    88   bjid = res = NULL;
       
    89   msg = NULL;
       
    90 
       
    91   for ( ; args->name; args++) {
       
    92     if (!g_strcmp0(args->name, "jid"))
       
    93       bjid = args->value;
       
    94     else if (!g_strcmp0(args->name, "resource"))
       
    95       res = args->value;
       
    96     else if (!g_strcmp0(args->name, "message"))
       
    97       msg = args->value;
       
    98     else if (!g_strcmp0(args->name, "groupchat")) {
       
    99       if (!g_strcmp0(args->value, "true"))
       
   100         muc = TRUE;
       
   101     }
       
   102   }
       
   103 
       
   104   if (muc && bjid && res && msg) {
       
   105     GSList *room_elt;
       
   106     struct lastm_T *lastm_item;
       
   107     const gchar *mynick = NULL;
       
   108 
       
   109     room_elt = roster_find(bjid, jidsearch, ROSTER_TYPE_ROOM);
       
   110     if (room_elt)
       
   111       mynick = buddy_getnickname(room_elt->data);
       
   112 
       
   113     if (!mynick || !g_strcmp0(res, mynick))
       
   114       return;
       
   115 
       
   116     if (!g_strstr_len(msg, -1, mynick))
       
   117       return;
       
   118 
       
   119     lastm_item = g_new(struct lastm_T, 1);
       
   120     lastm_item->mucname  = g_strdup(bjid);
       
   121     lastm_item->nickname = g_strdup(res);
       
   122     lastm_item->msg      = g_strdup(msg);
       
   123     lastmsg_list = g_slist_append(lastmsg_list, lastm_item);
       
   124   }
       
   125 }
       
   126 
       
   127 static void last_status_hh(guint32 hid, hk_arg_t *args, gpointer userdata)
       
   128 {
       
   129   gboolean not_away = FALSE;
       
   130 
       
   131   for ( ; args->name; args++) {
       
   132     if (!g_strcmp0(args->name, "new_status")) {
       
   133       if (args->value &&
       
   134           (args->value[0] != imstatus2char[away]) &&
       
   135           (args->value[0] != imstatus2char[notavail])) {
       
   136         not_away = TRUE;
       
   137         break;
       
   138       }
       
   139     }
       
   140   }
       
   141   if (!not_away || !lastmsg_list) return;
       
   142 
       
   143   scr_log_print(LPRINT_NORMAL, "Looks like you're back...");
       
   144   scr_log_print(LPRINT_NORMAL, "I've got news for you, use /lastmsg to "
       
   145                 "read your messages!");
       
   146 }
       
   147 
       
   148 /* Initialization */
       
   149 static void lastmsg_init(void)
       
   150 {
       
   151   /* Add command */
       
   152   cmd_add("lastmsg", "Display last missed messages", 0, 0, do_lastmsg, NULL);
       
   153 
       
   154   hk_add_handler(last_message_hh, HOOK_MESSAGE_IN, NULL);
       
   155   hk_add_handler(last_status_hh, HOOK_MY_STATUS_CHANGE, NULL);
       
   156 }
       
   157 
       
   158 /* Deinitialization */
       
   159 static void lastmsg_uninit(void)
       
   160 {
       
   161   /* Unregister command */
       
   162   cmd_del("lastmsg");
       
   163   hk_del_handler(last_message_hh, NULL);
       
   164   hk_del_handler(last_status_hh, NULL);
       
   165 
       
   166   for (GSList *li = lastmsg_list; li ; li = g_slist_next(li)) {
       
   167     struct lastm_T *lastm_item = li->data;
       
   168     g_free(lastm_item->mucname);
       
   169     g_free(lastm_item->nickname);
       
   170     g_free(lastm_item->msg);
       
   171   }
       
   172   g_slist_free(lastmsg_list);
       
   173   lastmsg_list = NULL;
       
   174 }
       
   175 
       
   176 /* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */