* has_only_html_part - функция возвращает TRUE, если в сообщении есть только одна HTML часть
* compare_recipients_distance - вычисляет процент схожих получателей письма. Принимает аргумент - порог в процентах похожести.
* is_recipients_sorted - возвращает TRUE, если список получателей сортирован (работает только если число получателей >= 5).
+
+Модуль chartable.
+================
+
+Модуль предназначен для поиска слов со смешанными символами, например:
+kашa - часть в латинице, а часть в кириллице.
+Параметры модуля:
+
+.module 'chartable' {
+ metric = "default";
+ symbold = "R_MIXED_CHARSET";
+ threshold = "0.1";
+};
+
+threshold - это отношение переходов между кодировками к общему числу символов в словах, например, имеем слово
+"kаша" (первая буква латинская), тогда общее число переходов - 3, а число переходов между кодировками - 1, тогда
+отношение - 1/3.
+
+Для включения модуля его необходимо добавить в список mime_filters:
+mime_filters = "chartable";
}
static gboolean
-check_part (struct mime_text_part *part)
+check_part (struct mime_text_part *part, gboolean raw_mode)
{
- char *p, *p1;
+ unsigned char *p, *p1;
gunichar c, t;
GUnicodeScript scc, sct;
uint32_t mark = 0, total = 0;
uint32_t remain = part->content->len;
- if (part->is_raw) {
- return FALSE;
- }
-
p = part->content->data;
- while (remain > 0) {
- c = g_utf8_get_char (p);
- scc = g_unichar_get_script (c);
- p1 = g_utf8_next_char (p);
- remain -= p1 - p;
- p = p1;
-
- if (remain > 0) {
- t = g_utf8_get_char (p);
- sct = g_unichar_get_script (t);
- if (g_unichar_isalnum (c) && g_unichar_isalnum (t)) {
- /* We have two unicode alphanumeric characters, so we can check its script */
- if (sct != scc) {
- mark ++;
- }
+ if (part->is_raw || raw_mode) {
+ while (remain > 1) {
+ if ((g_ascii_isalpha (*p) && (*(p + 1) & 0x80)) ||
+ ((*p & 0x80) && g_ascii_isalpha (*(p + 1)))) {
+ mark ++;
total ++;
}
+ /* Current and next symbols are of one class */
+ else if (((*p & 0x80) && (*(p + 1) & 0x80)) ||
+ (g_ascii_isalpha (*p) && g_ascii_isalpha (*(p + 1)))) {
+ total ++;
+ }
+ p ++;
+ remain --;
+ }
+ }
+ else {
+ while (remain > 0) {
+ c = g_utf8_get_char (p);
+ scc = g_unichar_get_script (c);
p1 = g_utf8_next_char (p);
remain -= p1 - p;
p = p1;
+
+ if (remain > 0) {
+ t = g_utf8_get_char (p);
+ sct = g_unichar_get_script (t);
+ if (g_unichar_isalnum (c) && g_unichar_isalnum (t)) {
+ /* We have two unicode alphanumeric characters, so we can check its script */
+ if (sct != scc) {
+ mark ++;
+ }
+ total ++;
+ }
+ p1 = g_utf8_next_char (p);
+ remain -= p1 - p;
+ p = p1;
+ }
}
}
{
GList *cur;
- /* XXX: write translation tables for this */
- if (task->cfg->raw_mode) {
- msg_warn ("chartable_mime_filter: cannot work in non-unicode mode");
- return 0;
- }
-
cur = g_list_first (task->text_parts);
while (cur) {
- if (check_part ((struct mime_text_part *)cur->data)) {
+ if (check_part ((struct mime_text_part *)cur->data, task->cfg->raw_mode)) {
insert_result (task, chartable_module_ctx->metric, chartable_module_ctx->symbol, 1, NULL);
}
cur = g_list_next (cur);