Add lastmsg module
authorMikael Berthe <mikael@lilotux.net>
Sun, 14 Mar 2010 16:59:12 +0100
changeset 10 14f4f6dcc75a
parent 9 3a4ddded06f2
child 11 573a48de8ee1
Add lastmsg module
Makefile.am
configure.ac
lastmsg/Makefile.am
lastmsg/lastmsg.c
--- a/Makefile.am	Sun Mar 14 12:20:33 2010 +0100
+++ b/Makefile.am	Sun Mar 14 16:59:12 2010 +0100
@@ -1,1 +1,1 @@
-SUBDIRS = comment extsay clock
+SUBDIRS = clock comment extsay lastmsg
--- a/configure.ac	Sun Mar 14 12:20:33 2010 +0100
+++ b/configure.ac	Sun Mar 14 16:59:12 2010 +0100
@@ -106,6 +106,9 @@
 AC_ARG_ENABLE(module-extsay,
               AC_HELP_STRING([--enable-module-extsay], [enable module extsay]),
               enable_module_extsay=$enableval)
+AC_ARG_ENABLE(module-lastmsg,
+              AC_HELP_STRING([--enable-module-lastmsg], [enable module lastmsg]),
+              enable_module_lastmsg=$enableval)
 
 AM_CONDITIONAL([INSTALL_MODULE_CLOCK],
                [test x"${enable_all_modules}" = x"yes" -o \
@@ -119,8 +122,13 @@
                [test x"${enable_all_modules}" = x"yes" -o \
                      x"${enable_module_extsay}" = x"yes"])
 
+AM_CONDITIONAL([INSTALL_MODULE_LASTMSG],
+               [test x"${enable_all_modules}" = x"yes" -o \
+                     x"${enable_module_lastmsg}" = x"yes"])
+
 AC_CONFIG_FILES([clock/Makefile
                  comment/Makefile
                  extsay/Makefile
+                 lastmsg/Makefile
                  Makefile])
 AC_OUTPUT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lastmsg/Makefile.am	Sun Mar 14 16:59:12 2010 +0100
@@ -0,0 +1,11 @@
+
+if INSTALL_MODULE_LASTMSG
+
+pkglib_LTLIBRARIES = liblastmsg.la
+liblastmsg_la_SOURCES = lastmsg.c
+liblastmsg_la_LDFLAGS = -module -avoid-version -shared
+
+LDADD = $(GLIB_LIBS) $(MCABBER_LIBS)
+AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(MCABBER_CFLAGS)
+
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lastmsg/lastmsg.c	Sun Mar 14 16:59:12 2010 +0100
@@ -0,0 +1,176 @@
+/*
+   Copyright 2010 Mikael Berthe
+
+  Module "lastmsg"    -- adds a /lastmsg command
+                         Displays last personal messages
+
+  This modules stores messages received in a MUC room while
+  you are away (or not available) if they contain your nickname.
+  When you're back, you can display them in the status window with
+  the /lastmsg command.
+  Note that this module is dumb: if your nick is foo and somebody
+  says "foobar" the message will be stored!
+
+This module is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <mcabber/modules.h>
+#include <mcabber/commands.h>
+#include <mcabber/hooks.h>
+#include <mcabber/xmpp.h>
+#include <mcabber/logprint.h>
+
+static void lastmsg_init(void);
+static void lastmsg_uninit(void);
+
+/* Module description */
+module_info_t info_lastmsg = {
+        .branch         = MCABBER_BRANCH,
+        .api            = MCABBER_API_VERSION,
+        .version        = "0.01",
+        .description    = "Add a command /lastmsg",
+        .requires       = NULL,
+        .init           = lastmsg_init,
+        .uninit         = lastmsg_uninit,
+        .next           = NULL,
+};
+
+static GSList *lastmsg_list;
+
+struct lastm_T {
+    gchar *mucname;
+    gchar *nickname;
+    gchar *msg;
+};
+
+static void do_lastmsg(char *args)
+{
+  if (!lastmsg_list) {
+    scr_log_print(LPRINT_NORMAL, "You have no new message.");
+    return;
+  }
+
+  for (GSList *li = lastmsg_list; li ; li = g_slist_next(li)) {
+    struct lastm_T *lastm_item = li->data;
+    scr_LogPrint(LPRINT_NORMAL, "In <#%s>, \"%s\" said:\n%s",
+                 lastm_item->mucname, lastm_item->nickname,
+                 lastm_item->msg);
+    g_free(lastm_item->mucname);
+    g_free(lastm_item->nickname);
+    g_free(lastm_item->msg);
+  }
+  g_slist_free(lastmsg_list);
+  lastmsg_list = NULL;
+}
+
+static void last_message_hh(guint32 hid, hk_arg_t *args, gpointer userdata)
+{
+  enum imstatus status;
+  const gchar *bjid, *res, *msg;
+  gboolean muc = FALSE;
+
+  status = xmpp_getstatus();
+
+  if (status != notavail && status != away)
+    return;
+
+  bjid = res = NULL;
+  msg = NULL;
+
+  for ( ; args->name; args++) {
+    if (!g_strcmp0(args->name, "jid"))
+      bjid = args->value;
+    else if (!g_strcmp0(args->name, "resource"))
+      res = args->value;
+    else if (!g_strcmp0(args->name, "message"))
+      msg = args->value;
+    else if (!g_strcmp0(args->name, "groupchat")) {
+      if (!g_strcmp0(args->value, "true"))
+        muc = TRUE;
+    }
+  }
+
+  if (muc && bjid && res && msg) {
+    GSList *room_elt;
+    struct lastm_T *lastm_item;
+    const gchar *mynick = NULL;
+
+    room_elt = roster_find(bjid, jidsearch, ROSTER_TYPE_ROOM);
+    if (room_elt)
+      mynick = buddy_getnickname(room_elt->data);
+
+    if (!mynick || !g_strcmp0(res, mynick))
+      return;
+
+    if (!g_strstr_len(msg, -1, mynick))
+      return;
+
+    lastm_item = g_new(struct lastm_T, 1);
+    lastm_item->mucname  = g_strdup(bjid);
+    lastm_item->nickname = g_strdup(res);
+    lastm_item->msg      = g_strdup(msg);
+    lastmsg_list = g_slist_append(lastmsg_list, lastm_item);
+  }
+}
+
+static void last_status_hh(guint32 hid, hk_arg_t *args, gpointer userdata)
+{
+  gboolean not_away = FALSE;
+
+  for ( ; args->name; args++) {
+    if (!g_strcmp0(args->name, "new_status")) {
+      if (args->value &&
+          (args->value[0] != imstatus2char[away]) &&
+          (args->value[0] != imstatus2char[notavail])) {
+        not_away = TRUE;
+        break;
+      }
+    }
+  }
+  if (!not_away || !lastmsg_list) return;
+
+  scr_log_print(LPRINT_NORMAL, "Looks like you're back...");
+  scr_log_print(LPRINT_NORMAL, "I've got news for you, use /lastmsg to "
+                "read your messages!");
+}
+
+/* Initialization */
+static void lastmsg_init(void)
+{
+  /* Add command */
+  cmd_add("lastmsg", "Display last missed messages", 0, 0, do_lastmsg, NULL);
+
+  hk_add_handler(last_message_hh, HOOK_MESSAGE_IN, NULL);
+  hk_add_handler(last_status_hh, HOOK_MY_STATUS_CHANGE, NULL);
+}
+
+/* Deinitialization */
+static void lastmsg_uninit(void)
+{
+  /* Unregister command */
+  cmd_del("lastmsg");
+  hk_del_handler(last_message_hh, NULL);
+  hk_del_handler(last_status_hh, NULL);
+
+  for (GSList *li = lastmsg_list; li ; li = g_slist_next(li)) {
+    struct lastm_T *lastm_item = li->data;
+    g_free(lastm_item->mucname);
+    g_free(lastm_item->nickname);
+    g_free(lastm_item->msg);
+  }
+  g_slist_free(lastmsg_list);
+  lastmsg_list = NULL;
+}
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */