Example #1
0
static gboolean writing_msg(PurpleConversation *conv, PurpleMessage *msg, gpointer _unused)
{
	GString *t;
	GList *iter, *urls, *next;
	int c = 0;

	if (purple_message_get_flags(msg) & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_INVISIBLE))
		return FALSE;

	urls = g_object_get_data(G_OBJECT(conv), "TinyURLs");
	if (urls != NULL) /* message was cancelled somewhere? Reset. */
		g_list_foreach(urls, free_urls, NULL);
	g_list_free(urls);
	urls = extract_urls(purple_message_get_contents(msg));
	if (!urls)
		return FALSE;

	t = g_string_new(g_strdup(purple_message_get_contents(msg)));
	for (iter = urls; iter; iter = next) {
		next = iter->next;
		if (g_utf8_strlen((char *)iter->data, -1) >= purple_prefs_get_int(PREF_LENGTH)) {
			int pos, x = 0;
			gchar *j, *s, *str, *orig;
			glong len = g_utf8_strlen(iter->data, -1);
			s = g_strdup(t->str);
			orig = s;
			str = g_strdup_printf("[%d]", ++c);
			while ((j = strstr(s, iter->data))) { /* replace all occurrences */
				pos = j - orig + (x++ * 3);
				s = j + len;
				t = g_string_insert(t, pos + len, str);
				if (*s == '\0') break;
			}
			g_free(orig);
			g_free(str);
			continue;
		} else {
			g_free(iter->data);
			urls = g_list_delete_link(urls, iter);
		}
	}
	purple_message_set_contents(msg, t->str);
	g_string_free(t, TRUE);
	if (conv != NULL)
		g_object_set_data(G_OBJECT(conv), "TinyURLs", urls);
	return FALSE;
}
Example #2
0
char *notification_extract_markup_urls(char **str_ptr) {
    char *start, *end, *replace_buf, *str, *urls = NULL, *url, *index_buf;
    int linkno = 1;

    str = *str_ptr;
    while ((start = strstr(str, "<a href")) != NULL) {
        end = strstr(start, ">");
        if (end != NULL) {
            replace_buf = strndup(start, end - start + 1);
            url = extract_urls(replace_buf);
            if (url != NULL) {
                str = string_replace(replace_buf, "[", str);

                index_buf = g_strdup_printf("[#%d]", linkno++);
                if (urls == NULL) {
                    urls = g_strconcat(index_buf, " ", url, NULL);
                } else {
                    char *tmp = urls;
                    urls = g_strconcat(tmp, "\n", index_buf, " ", url, NULL);
                    free(tmp);
                }

                index_buf[0] = ' ';
                str = string_replace("</a>", index_buf, str);
                free(index_buf);
                free(url);
            } else {
                str = string_replace(replace_buf, "", str);
                str = string_replace("</a>", "", str);
            }
            free(replace_buf);
        } else {
            break;
        }
    }
    *str_ptr = str;
    return urls;
}
Example #3
0
/*
 * Initialize the given notification and add it to
 * the queue. Replace notification with id if id > 0.
 */
int notification_init(notification * n, int id)
{

    if (n == NULL)
        return -1;

    if (strcmp("DUNST_COMMAND_PAUSE", n->summary) == 0) {
        pause_display = true;
        return 0;
    }

    if (strcmp("DUNST_COMMAND_RESUME", n->summary) == 0) {
        pause_display = false;
        return 0;
    }

    n->script = NULL;
    n->text_to_render = NULL;

    n->format = settings.format;

    rule_apply_all(n);

    n->urls = notification_extract_markup_urls(&(n->body));

    n->msg = string_replace("%a", n->appname, g_strdup(n->format));
    n->msg = string_replace("%s", n->summary, n->msg);
    if (n->icon) {
        n->msg = string_replace("%I", basename(n->icon), n->msg);
        n->msg = string_replace("%i", n->icon, n->msg);
    }
    n->msg = string_replace("%b", n->body, n->msg);
    if (n->progress) {
        char pg[10];
        sprintf(pg, "[%3d%%]", n->progress - 1);
        n->msg = string_replace("%p", pg, n->msg);
    } else {
        n->msg = string_replace("%p", "", n->msg);
    }

    if (!settings.allow_markup)
        n->msg = notification_fix_markup(n->msg);
    else if (!settings.ignore_newline) {
        n->msg = string_replace("<br>", "\n", n->msg);
        n->msg = string_replace("<br />", "\n", n->msg);
    }

    while (strstr(n->msg, "\\n") != NULL)
        n->msg = string_replace("\\n", "\n", n->msg);

    if (settings.ignore_newline)
        while (strstr(n->msg, "\n") != NULL)
            n->msg = string_replace("\n", " ", n->msg);

    n->msg = g_strstrip(n->msg);

    n->dup_count = 0;

    /* check if n is a duplicate */
    if (settings.stack_duplicates) {
        for (GList * iter = g_queue_peek_head_link(queue); iter;
                iter = iter->next) {
            notification *orig = iter->data;
            if (strcmp(orig->appname, n->appname) == 0
                    && strcmp(orig->summary, n->summary) == 0
                    && strcmp(orig->body, n->body) == 0) {
                /* If the progress differs this was probably intended to replace the notification
                 * but notify-send was used. So don't increment dup_count in this case
                 */
                if (orig->progress == n->progress) {
                    orig->dup_count++;
                } else {
                    orig->progress = n->progress;
                }
                /* notifications that differ only in progress hints should be expected equal,
                 * but we want the latest message, with the latest hint value
                 */
                free(orig->msg);
                orig->msg = strdup(n->msg);
                notification_free(n);
                wake_up();
                return orig->id;
            }
        }

        for (GList * iter = g_queue_peek_head_link(displayed); iter;
                iter = iter->next) {
            notification *orig = iter->data;
            if (strcmp(orig->appname, n->appname) == 0
                    && strcmp(orig->summary, n->summary) == 0
                    && strcmp(orig->body, n->body) == 0) {
                /* notifications that differ only in progress hints should be expected equal,
                 * but we want the latest message, with the latest hint value
                 */
                free(orig->msg);
                orig->msg = strdup(n->msg);
                /* If the progress differs this was probably intended to replace the notification
                 * but notify-send was used. So don't increment dup_count in this case
                 */
                if (orig->progress == n->progress) {
                    orig->dup_count++;
                } else {
                    orig->progress = n->progress;
                }
                orig->start = time(NULL);
                notification_free(n);
                wake_up();
                return orig->id;
            }
        }
    }

    /* urgency > CRIT -> array out of range */
    n->urgency = n->urgency > CRIT ? CRIT : n->urgency;

    if (!n->color_strings[ColFG]) {
        n->color_strings[ColFG] = xctx.color_strings[ColFG][n->urgency];
    }

    if (!n->color_strings[ColBG]) {
        n->color_strings[ColBG] = xctx.color_strings[ColBG][n->urgency];
    }

    n->timeout =
        n->timeout == -1 ? settings.timeouts[n->urgency] : n->timeout;
    n->start = 0;

    if (n->icon == NULL) {
        n->icon = settings.icons[n->urgency];
    }
    else if (strlen(n->icon) <= 0) {
        free(n->icon);
        n->icon = settings.icons[n->urgency];
    }

    if (n->category == NULL) {
        n->category = "";
    }

    n->timestamp = time(NULL);

    n->redisplayed = false;

    n->first_render = true;

    if (id == 0) {
        n->id = ++next_notification_id;
    } else {
        notification_close_by_id(id, -1);
        n->id = id;
    }

    if (strlen(n->msg) == 0) {
        notification_close(n, 2);
        printf("skipping notification: %s %s\n", n->body, n->summary);
    } else {
        g_queue_insert_sorted(queue, n, notification_cmp_data, NULL);
    }

    char *tmp = g_strconcat(n->summary, " ", n->body, NULL);

    char *tmp_urls = extract_urls(tmp);
    if (tmp_urls != NULL) {
        if (n->urls != NULL) {
            n->urls = string_append(n->urls, tmp_urls, "\n");
            free(tmp_urls);
        } else {
            n->urls = tmp_urls;
        }
    }

    if (n->actions) {
        n->actions->dmenu_str = NULL;
        for (int i = 0; i < n->actions->count; i += 2) {
            char *human_readable = n->actions->actions[i + 1];
            string_replace_char('[', '(', human_readable); // kill square brackets
            string_replace_char(']', ')', human_readable);

            n->actions->dmenu_str =
                string_append(n->actions->dmenu_str,
                              g_strdup_printf("#%s [%s]", human_readable,
                                              n->appname),
                              "\n");
        }
    }

    free(tmp);

    if (settings.print_notifications)
        notification_print(n);

    return n->id;
}