/xchat-gnome-0.26.2/plugins/url_scraper/urlscraper.c
C | 236 lines | 183 code | 51 blank | 2 comment | 16 complexity | 484e753dbb9487888f244ccd20f8355b MD5 | raw file
Possible License(s): GPL-2.0
- #include <config.h>
- #include <glib/gi18n.h>
- #include <sys/types.h>
- #include <regex.h>
- #include <gtk/gtk.h>
- #include <stdlib.h>
- #include <string.h>
- #include <gconf/gconf-client.h>
- #include <time.h>
- #include "xchat-plugin.h"
- #define PVERSION "0.2"
- #define URLREGEX "(ht|f)tps?://[~a-z0-9./_=#%&?,-]+[a-z0-9]+"
- #define EMAILREGEX "[a-z0-9.+_-]+@([0-9a-z-]+\\.)+[a-z]+"
- static xchat_plugin *ph; // Plugin handle.
- static regex_t *email; // Regex that matches e-mail addresses.
- static regex_t *url; // Regex that matches urls.
- static int urls, history; // Current total in the scraper and max history.
- static gboolean timestamps; // Show timestamps?
- static GtkWidget *window;
- static GtkListStore *list_store;
- void url_open (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data);
- void xchat_plugin_get_info (char **plugin_name, char **plugin_desc, char **plugin_version, void **reserved);
- int xchat_plugin_init (xchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg);
- int xchat_plugin_deinit (void);
- static gboolean delete_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
- {
- return TRUE;
- }
- static void make_window ()
- {
- GtkWidget *treeview, *scrolled;
- GtkTreeViewColumn *nick_col, *chan_col, *url_col, *time_col;
- GtkCellRenderer *nick_rend, *chan_rend, *url_rend, *time_rend;
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), _("xchat URL scraper"));
- gtk_window_set_default_size (GTK_WINDOW(window), 400, 400);
- g_signal_connect (G_OBJECT(window), "delete-event", G_CALLBACK(delete_cb), 0);
- list_store = gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- treeview = gtk_tree_view_new ();
- gtk_tree_view_set_model (GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(list_store));
- time_rend = gtk_cell_renderer_text_new ();
- time_col = gtk_tree_view_column_new_with_attributes (_("Time"), time_rend, "text", 0, NULL);
- gtk_tree_view_column_set_visible (time_col, timestamps);
- gtk_tree_view_column_set_resizable (time_col, TRUE);
- nick_rend = gtk_cell_renderer_text_new ();
- nick_col = gtk_tree_view_column_new_with_attributes (_("Nick"), nick_rend, "text", 1, NULL);
- gtk_tree_view_column_set_resizable (nick_col, TRUE);
- chan_rend = gtk_cell_renderer_text_new ();
- chan_col = gtk_tree_view_column_new_with_attributes (_("Channel"), chan_rend, "text", 2, NULL);
- gtk_tree_view_column_set_resizable (chan_col, TRUE);
- url_rend = gtk_cell_renderer_text_new ();
- g_object_set (G_OBJECT(url_rend), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- url_col = gtk_tree_view_column_new_with_attributes (_("URL"), url_rend, "text", 3, NULL);
- gtk_tree_view_column_set_resizable (url_col, TRUE);
- gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), time_col);
- gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), nick_col);
- gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), chan_col);
- gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), url_col);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), TRUE);
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled), treeview);
- gtk_container_add (GTK_CONTAINER(window), scrolled);
- g_signal_connect (G_OBJECT(treeview), "row-activated", G_CALLBACK(url_open), NULL);
- g_object_set (G_OBJECT(treeview), "enable-search", FALSE, NULL);
- gtk_widget_show_all (window);
- }
- static void add_match (char **word, regmatch_t match, gboolean isurl)
- {
- int len;
- const char *chan;
- time_t footime;
- struct tm *time_struct;
- char *url_match, time_str[9];
- GtkTreeIter iter;
- len = match.rm_eo - match.rm_so;
- url_match = malloc (len + 1);
- memset (url_match, 0, len + 1);
- strncpy (url_match, word[2] + match.rm_so, len);
- chan = xchat_get_info (ph, "channel");
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(list_store), &iter)) {
- char *entry;
- do {
- gtk_tree_model_get (GTK_TREE_MODEL(list_store), &iter, 3, &entry, -1);
- if (strcmp (entry, url_match) == 0) {
- free (url_match);
- return;
- }
- } while (gtk_tree_model_iter_next (GTK_TREE_MODEL(list_store), &iter));
- }
- if (urls >= history) {
- gtk_tree_model_get_iter_first (GTK_TREE_MODEL(list_store), &iter);
- gtk_list_store_remove (list_store, &iter);
- }
- else
- urls++;
- /* Get time stamp. */
- footime = time (NULL);
- time_struct = localtime (&footime);
- sprintf (time_str, "%02d:%02d:%02d",
- time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
- gtk_list_store_append (list_store, &iter);
- gtk_list_store_set (list_store, &iter,
- 0, time_str, 1, word[1], 2, chan, 3, url_match, 4, isurl, -1);
- }
- static int grabURL (char **word, void *userdata)
- {
- regmatch_t match;
- if (regexec (url, word[2], 1, &match, REG_NOTBOL | REG_NOTEOL) == 0)
- add_match (word, match, TRUE);
- else if (regexec (email, word[2], 1, &match, REG_NOTBOL | REG_NOTEOL) == 0)
- add_match (word, match, FALSE);
- return XCHAT_EAT_NONE;
- }
- void xchat_plugin_get_info (char **plugin_name,
- char **plugin_desc,
- char **plugin_version,
- void **reserved)
- {
- *plugin_name = _("URL Scraper");
- *plugin_desc = _("Grabs URLs and puts them in a separate window for easy viewing.");
- *plugin_version = PVERSION;
- if (reserved)
- *reserved = NULL;
- }
- void url_open (GtkTreeView *treeview, GtkTreePath *path,
- GtkTreeViewColumn *column, gpointer user_data)
- {
- gchar *cur_url = NULL;
- gboolean isurl;
- GtkTreeModel *model;
- GtkTreeSelection *selection;
- GError *err = NULL;
- GtkTreeIter iter;
- model = gtk_tree_view_get_model (treeview);
- selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- gtk_tree_model_get (model, &iter, 3, &cur_url, 4, &isurl, -1);
- if (isurl)
- gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (treeview)),
- cur_url, gtk_get_current_event_time (), &err);
- if (err) {
- g_warning ("Unable to open %s: %s", cur_url, err->message);
- g_error_free (err);
- }
- }
- }
- int xchat_plugin_init (xchat_plugin *plugin_handle,
- char **plugin_name,
- char **plugin_desc,
- char **plugin_version,
- char *arg)
- {
- GConfClient *client = gconf_client_get_default ();
- ph = plugin_handle;
- xchat_plugin_get_info (plugin_name, plugin_desc, plugin_version, NULL);
- url = malloc (sizeof (regex_t));
- if (regcomp (url, URLREGEX, REG_ICASE | REG_EXTENDED)) {
- xchat_print (ph, _("URL Scraper failed to load: couldn't compile URL regex.\n"));
- return 0;
- }
- email = malloc (sizeof (regex_t));
- if (regcomp (email, EMAILREGEX, REG_ICASE | REG_EXTENDED)) {
- xchat_print (ph, _("URL Scraper failed to load: couldn't compile e-mail regex.\n"));
- return 0;
- }
- urls = 0;
- /* Set our prefs from GConf. */
- history = gconf_client_get_int (client, "/apps/xchat/plugins/urlscraper/history", NULL);
- timestamps = gconf_client_get_bool (client, "/apps/xchat/plugins/urlscraper/timestamps", NULL);
- make_window ();
- xchat_hook_print (ph, "Channel Message", XCHAT_PRI_NORM, grabURL, 0);
- xchat_hook_print (ph, "Private Message to Dialog", XCHAT_PRI_NORM, grabURL, 0);
- xchat_print (ph, _("URL Scraper loaded.\n"));
- return 1;
- }
- int xchat_plugin_deinit (void)
- {
- gtk_widget_destroy (window);
- regfree (url);
- regfree (email);
- xchat_print (ph, _("URL Scraper unloaded.\n"));
- return 1;
- }