Fix remaining cases of bug #2923
[claws.git] / src / plugins / perl / cm_perl.pod
1 =head1 NAME
2
3 cm_perl -- A Perl Plugin for Claws Mail
4
5 =head1 DESCRIPTION
6
7 This plugin provides an extended filtering engine for the email
8 client Claws Mail. It allows for the use of full Perl power
9 in email filters.
10
11 =head1 QUICK START
12
13 To get started, you can use the B<matcherrc2perlfilter.pl> script
14 in the B<tools>-directory to translate your old filtering rules to
15 Perl. Simply execute the script and follow the instructions.
16 (note that with recent versions of Claws Mail, this script might not
17 work due to upstream syntax changes. This will get updated in the
18 future. Send me an email if you have problems getting started).
19
20 However, you might want to consider reading the rest of this
21 manual and rewriting your rules if you choose to use the plugin,
22 since the Perl code produced by this script is not exactly
23 pretty.
24
25 Don't speak Perl? No problem, L<"perldoc perlintro"|perlintro>
26 should give you enough information to do fancy stuff.
27
28 =head1 USAGE
29
30 The Perl plugin expects a Perl script file called B<perl_filter>
31 in Claws Mail' config directory (usually $HOME/.claws-mail --
32 try `claws-mail --config-dir' if you're unsure). If that file
33 doesn't exist on plugin start, an empty one is created.  This
34 file, which doesn't need to start with a sha-bang (!#/bin/perl),
35 holds the Perl instructions for your email filters. To encourage
36 some good manners, the code is executed in a C<use strict;>
37 environment.
38
39 Both Claws Mail' filtering B<conditions> and B<actions> are
40 mapped to Perl functions with corresponding names, wherever this
41 is possible.
42
43 =head1 FUNCTION LISTING
44
45 For a detailed function description, see section L</"FUNCTION
46 DESCRIPTIONS">, below.
47
48 =over 4
49
50 =item Standard Filtering Conditions
51
52  all, marked, unread, deleted, new, replied,
53  forwarded, locked, ignore_thread, colorlabel,
54  match, matchcase, regexp, S<regexpcase, test,
55  size_greater, size_smaller, size_equal,
56  score_greater, score_lower, score_equal, age_greater,
57  age_lower, partial, tagged
58
59 =item Standard Filtering Actions
60
61  mark, unmark, dele, mark_as_unread, mark_as_read,
62  lock, unlock, move, copy, color, execute,
63  hide, set_score, change_score, stop, forward,
64  forward_as_attachment, redirect, set_tag, unset_tag,
65  clear_tags
66
67 =item Fun stuff
68
69  header, body, filepath, extract_addresses,
70  move_to_trash, abort, addr_in_addressbook,
71  from_in_addressbook, get_attribute_value, SA_is_spam,
72  exit, manual, make_sure_folder_exists,
73  filter_log, filter_log_verbosity,
74  make_sure_tag_exists
75
76 =back
77
78 =head1 FUNCTION DESCRIPTIONS
79
80 In general, after the filtering invoked by the Perl script, the
81 mail is passed on to Claws' internal filtering engine, I<unless>
82 a B<final> rule was hit. Final rules stop not only the Perl
83 filtering script at the point of their occurence, but also
84 prevent processing that email by Claws' internal filtering engine
85 (this might sound confusing, but you are already familiar with
86 that concept from standard filters: After an email was
87 e.g. I<move>d, the following rules don't apply anymore).
88
89 Also, be careful with the way you quote. In particular, remember
90 that the @-sign has a special meaning in Perl, and gets
91 interpolated inside double quotes. See L<perlop/"Quote and
92 Quote-like Operators"> to learn more about quoting and
93 interpolation.
94
95
96 =head2 Standard Filtering Conditions
97
98 =over 8
99
100 =item all
101
102 Returns a true value. Available for completness only.
103
104 =item marked
105
106 Returns a true value if the marked flag is set, false otherwise.
107
108 =item unread
109
110 Returns a true value if the unread flag is set, false otherwise.
111
112 =item deleted
113
114 Returns a true value if the deleted flag is set, false otherwise.
115
116 =item new
117
118 Returns a true value if the new flag is set, false otherwise.
119
120 =item replied
121
122 Returns a true value if the replied flag is set, false otherwise.
123
124 =item forwarded
125
126 Returns a true value if the forwarded flag is set, false otherwise.
127
128 =item locked
129
130 Returns a true value if the locked flag is set, false otherwise.
131
132 =item ignore_thread
133
134 Returns a true value if the "Ignore Thread" flag is set, false otherwise.
135
136 =item colorlabel COLOR
137
138 =item colorlabel
139
140 Returns a true value if message has the color COLOR. COLOR can be
141 either a numeric value between 0 and 7 (with colors corresponding
142 to the internal filtering engine), or the english color name as
143 it is introduced in the filtering dialog (that is, one of: none,
144 orange, red, pink, sky blue, blue, green or brown, while upper
145 and lower case letters make no difference). If COLOR is omitted,
146 0 (none) is assumed.
147
148 =item size_greater SIZE
149
150 Returns a true value if message size is greater than SIZE, false otherwise.
151
152 =item size_smaller SIZE
153
154 Returns a true value if message size is smaller than SIZE, false otherwise.
155
156 =item size_equal SIZE
157
158 Returns a true value if message size is equal to SIZE, false otherwise.
159
160 =item score_greater SCORE
161
162 Returns a true value if message score is greater than SCORE, false otherwise.
163
164 =item score_lower SCORE
165
166 Returns a true value if message score is lower than SCORE, false otherwise.
167
168 =item score_equal SCORE
169
170 Returns a true value if message score is equal to SCORE, false otherwise.
171
172 =item age_greater AGE
173
174 Returns a true value if message age is greater than AGE, false otherwise.
175
176 =item age_lower AGE
177
178 Returns a true value if message age is lower than AGE, false otherwise.
179
180 =item partial
181
182 Returns a true value if message has only partially been
183 downloaded, false otherwise.
184
185 =item tagged
186
187 Returns a true value if the messages has one or more tags.
188
189 =item test
190
191 Corresponds the 'test' internal filtering rule. In particular, it
192 accepts the same symbols, namely:
193
194 =over
195
196 =item %%
197
198 %
199
200 =item %s
201
202 Subject
203
204 =item %f
205
206 From
207
208 =item %t
209
210 To
211
212 =item %c
213
214 Cc
215
216 =item %d
217
218 Date
219
220 =item %i
221
222 Message-ID
223
224 =item %n
225
226 Newsgroups
227
228 =item %r
229
230 References
231
232 =item %F
233
234 Filename -- should not be modified
235
236 =back
237
238 =item match WHERE WHAT
239
240 =item matchcase WHERE WHAT
241
242 =item regexp WHERE WHAT
243
244 =item regexpcase WHERE WHAT
245
246 The matching functions have a special syntax. The first argument
247 is either any of to_or_cc, body_part, headers_part, message, to,
248 from, subject, cc, newsgroups, inreplyto, references, or tag (those
249 strings may or may not be quoted), the patter matching works on
250 that area. If it is any other string (which must then be quoted),
251 this string is taken to be the name of a header field.
252
253 The second argument is the string to look for. For match,
254 matchcase, regexp and regexpcase we have case sensitive normal
255 matching, case insensitive normal matching, case sensitive
256 regular expression matching and case insensitive regular
257 expression pattern matching, respectively.
258
259 The functions return true if the pattern was found, false
260 otherwise.
261
262 Just as with the built-in filtering engine, the message body is
263 searched and provided as is - no character-set analysis is
264 done. Likewise, no HTML-tags are stripped. It should be possible
265 to use external modules or programs for these tasks though. If
266 you're doing that, drop me a message with your experiences.
267
268 With Perl having its strenghts in pattern matching, using Perl's
269 builtin operators are usually a better option than using these
270 functions.
271
272 =back
273
274 =head2 Standard Filtering Actions
275
276 The actions return a true value upon success, and 'undef' when an
277 error occured. I<Final> message rules are indicated. (See above
278 for a sketch what a final rule is)
279
280 =over 8
281
282 =item mark
283
284 Mark the message.
285
286 =item unmark
287
288 Unmark the message.
289
290 =item dele
291
292 Delete the message. Note the name change of Claws Mail'
293 "delete" to "dele". This is because "delete" is one of Perl's
294 builtin commands which cannot be redefined (if it can, tell me
295 how).
296
297 This is a I<final> rule.
298
299 =item mark_as_read
300
301 Mark the message as read
302
303 =item mark_as_unread
304
305 Mark the message as unread
306
307 =item lock
308
309 Lock the message
310
311 =item unlock
312
313 Remove the message lock
314
315 =item move DESTINATION
316
317 Move the message to folder DESTINATION. The folder notation is
318 the same that Claws Mail uses. You can copy & paste from the
319 move dialog of the normal filtering, until you get a feeling for
320 the notation.
321
322 This is a I<final> rule.
323
324 =item copy DESTINATION
325
326 Copy the message to folder DESTINATION. The folder notation is
327 the same that Claws Mail uses. You can copy & paste from the
328 move dialog of the normal filtering, until you get a feeling for
329 the notation.
330
331 =item execute COMMAND
332
333 This is the same as the test - rule from section L</"Standard
334 Filtering Conditions"> execpt that it always returns a true
335 value.
336
337 =item hide
338
339 Hide the message
340
341 =item set_score SCORE
342
343 Set message score to SCORE
344
345 =item change_score SCORE
346
347 Change message score by SCORE
348
349 =item stop
350
351 Stop Perl script at this point. Note that this is B<not> a final
352 rule, meaning that the email gets passed on to the internal
353 filtering engine. See "abort" below if you don't want that.
354
355 =item forward ACCOUNT, EMAIL
356
357 Forward the message to email address EMAIL, using the account ID
358 ACCOUNT as sender account. So far, you have to create a rule
359 in the normal filtering engine to find out that number.
360
361 =item forward_as_attachment, ACCOUNT EMAIL
362
363 Forward the message to email address EMAIL in an attachment,
364 using the account ID ACCOUNT as sender account. So far, you
365 have to create a rule in the normal filtering engine to find out
366 that number.
367
368 =item redirect ACCOUNT, EMAIL
369
370 Redirect the message to EMAIL, using the account ID ACCOUNT as
371 sender account. So far, you have to create a rule in the normal
372 filtering engine to find out that number.
373
374 =item set_tag TAG
375
376 Apply tag TAG. TAG must exist.
377
378 =item unset_tag TAG
379
380 Unset tag TAG.
381
382 =item clear_tags
383
384 Clear all tags.
385
386 =back
387
388 =head2 Fun stuff
389
390 =head3 Functions
391
392 =over 8
393
394 =item header ARG
395
396 =item header
397
398 If ARG is not given, returns a list of all header field names of
399 the mail.
400
401 If ARG is given, returns 'undef' if the header field ARG does not
402 exist in the email. Otherwise, it returns
403
404 =over
405
406 =item in scalar context
407
408 The value of the header field ARG.
409
410 =item in list context
411
412 A list of all available header field values. This is useful if a
413 header field occurs more than once in an email (eg the Received -
414 header).
415
416 =back
417
418 The header field "References" forms a special case. In a scalar context,
419 it returns the first reference. In a list context, it returns a list of
420 all references.
421
422 =item body
423
424 Returns the email body in a scalar.
425
426 =item filepath
427
428 Returns the file and path of the email that is currently filtered
429 (corresponds to the %F arguemnt in the 'test' rule).
430
431 =item extract_addresses
432
433 Extracts email addresses from a string and gives back a list of
434 addresses found. Currently an email address is found using the
435 regular expression '[-.+\w]+\@[-.+\w]+'. This will not find all
436 valid email addresses. Feel free to send me a better regexp.
437
438 =item move_to_trash
439
440 Move the email message to default trash folder.
441
442 This is a I<final> rule.
443
444 =item abort
445
446 Stop Perl script at this point.
447
448 In contrast to 'stop', this is a I<final> rule.
449
450 =item addr_in_addressbook EMAIL, ADDRESSBOOK
451
452 =item addr_in_addressbook EMAIL
453
454 Returns a true value if the email address EMAIL is in the addressbook
455 with the name ADDRESSBOOK. If ADDRESSBOOK is not given, returns
456 true if the email address is in any addressbook.
457
458 =item from_in_addressbook ADDRESSBOOK
459
460 =item from_in_addressbook
461
462 Checks if the email address found in the From-header is in
463 addressbook ADDRESSBOOK (or any, if omitted). It is implemented
464 as
465
466  my ($from) = extract_addresses(header("from"));
467  return 0 unless $from;
468  return addr_in_addressbook($from,@_);
469
470 so the same restrictions as to extract_addresses apply.
471
472 =item get_attribute_value EMAIL, ATTRIBUTE, ADDRESSBOOK
473
474 =item get_attribute_value EMAIL, ATTRIBUTE
475
476 Looks through the addressbook ADDRESSBOOK (or all addressbooks,
477 if omitted) for a contact with the an email address EMAIL. If
478 found, the function checks if this contact has a user attribute
479 with name ATTRIBUTE. It returns the value of this attribute, or
480 an empty string if it was not found. As usual, 'undef' is
481 returned if an error occured.
482
483 =item SA_is_spam
484
485 Is an alias to
486
487 not test 'spamc -c < %F > /dev/null'
488
489 =item exit
490
491 Has been redefined to be an alias to 'stop'. You shouldn't use
492 Perl's own 'exit' command, since it would exit Claws Mail.
493
494 =item manual
495
496 Returns a true value if the filter script was invoked manually,
497 that is, via the Tools menu.
498
499 =item make_sure_folder_exists IDENTIFIER
500
501 Returns a true value if the folder with id IDENTIFIER (e.g. #mh/Mail/foo/bar)
502 exists or could be created.
503
504 =item make_sure_tag_exists TAG
505
506 Returns a true value if the tag TAG exists or could be created.
507
508 =item filter_log SECTION, TEXT
509
510 =item filter_log TEXT
511
512 Writes TEXT to the filter logfile. SECTION can be any of
513
514 =over
515
516 =item *
517
518 "LOG_MANUAL"
519
520 =item *
521
522 "LOG_MATCH"
523
524 =item *
525
526 "LOG_ACTION"
527
528 =back
529
530 If the SECTION is omitted, "LOG_MANUAL" is assumed.
531
532 =item filter_log_verbosity VERBOSITY
533
534 =item filter_log_verbosity
535
536 Changes the filter log verbosity for the current mail. VERBOSITY
537 must be any of
538
539 =over 2
540
541 =item C<0>
542
543 Be silent
544
545 =item C<1>
546
547 Log MANUAL type
548
549 =item C<2>
550
551 Log Action type
552
553 =item C<3>
554
555 Log MATCH type
556
557 =back
558
559 For the meaning of those numbers, read section L</"LOGGING">. If
560 VERBOSITY is omitted, the filter logfile verbosity is not changed.
561
562 This function returns the filter_log_verbosity number before the
563 change (if any).
564
565 =back
566
567 =head3 Variables
568
569 =over 8
570
571 =item $permanent
572
573 This scalar keeps its value between filtered mail messages. On
574 plugin start, it is initialized to the empty string.
575
576 =back
577
578 =head1 LOGGING
579
580 To keep track of what has been done to the mails while filtering,
581 the plugin supports logging. Three verbosity levels are
582 recognized:
583
584 =over
585
586 =item C<0>
587
588 logging disabled
589
590 =item C<1>
591
592 log only manual messages, that is, messages introduced by the
593 C<filter_log> command in filter scripts
594
595 =item C<2>
596
597 log manual messages and filter actions
598
599 =item C<3>
600
601 log manual messages, filter actions and filter matches
602
603 =back
604
605 The messages are logged in Claws Mail' log window.
606 The default log level is 2. Log level 3 is not
607 recommended, because the matcher functions log a message if they
608 succeeded, and thus, if you have negative checks, you'll get
609 confusing entries. If you want to keep track of matching, do it
610 manually, using C<filter_log>, or do it by temporary enabling
611 matcher logging using C<filter_log_verbosity>.
612
613 The first time you unload this plugin (or shut down
614 Claws Mail), a section called B<[PerlPlugin]> will be created
615 in Claws Mail' configuration file B<clawsrc>, containing
616 one variable:
617
618  * filter_log_verbosity
619
620 If you want to change the default behaviour, you can edit this
621 line. Make sure Claws Mail is not running while you do
622 this.
623
624 It will be possible to access these setting via the GUI, as soon
625 as I find the time to write a corresponding GTK plugin, or
626 somebody else is interested in contributing that.
627
628 =head1 EXAMPLE
629
630 This section lists a small example of a Perl script file. I'm
631 sure you get the idea..
632
633  #-8<----------------------------------------------------
634  # -*- perl -*-
635
636  # local functions
637
638  # Learn ham messages, and move them to specified folder. This is
639  # useful for making sure a bayes filter sees ham as well.
640  sub learn_and_move {
641      execute('put command to learn ham here');
642      move(@_);
643  }
644
645  # Two-stage spam filter. Every email that scores higher than 15
646  # on SpamAssassin gets moved into the default trash folder.
647  # All mails lower than that, but higher than SpamAssassin's
648  # 'required_hits' go into  #mh/mail/Spam.
649  sub spamcheck {
650      my $surely_spam = 15;
651      my $filepath = filepath;
652      my $spamc = `spamc -c < $filepath`;
653      my ($value,$threshold) = ($spamc =~ m|([-.,0-9]+)/([-.,0-9]+)|);
654      if($value >= $surely_spam) {
655         mark_as_read;
656         move_to_trash;
657      }
658      if($value >= $threshold) {mark_as_read; move '#mh/mail/Spam';}
659  }
660
661  # Perl script execution starts here.
662
663  # Some specific sorting
664  learn_and_move '#mh/mail/MailLists/Claws Mail/user'
665    if matchcase('sender','claws-mail-users-admin@lists.sourceforge.net');
666  learn_and_move '#mh/mail/MailLists/Sylpheed'
667    if matchcase('list-id','sylpheed.good-day.net');
668
669  # Implement imcomming folders using addressbook
670  # attributes. Target folders for specific email addresses are
671  # stored directly in the addressbook. This way, if an email
672  # address changes, we only have to update the addressbook, not
673  # the filter rules! Besides that, we can greatly unclutter the
674  # filter script.
675
676  # get the email address in the from header
677  my $fromheader = header "from";
678  my ($from) = extract_addresses $fromheader;
679
680  # check if this email address has an associated attribute
681  # called "incomming_folder". If if has, the value of this
682  # attribute is supposed to be the target folder.
683  my $value = get_attribute_value $from, "incomming_folder";
684  learn_and_move($value) if $value;
685
686  # An example of a whitelist: If the from-address is in my
687  # "office" addressbook, move the mail to folder #mh/mail/office
688  learn_and_move '#mh/mail/office' if from_in_addressbook("office");
689
690  # If the from-address is in any other addressbook, move the
691  # mail to folder #mh/mail/inbox/known
692  learn_and_move '#mh/mail/inbox/known' if from_in_addressbook;
693
694  # Feed the remaining mails through SpamAssassin.
695  spamcheck;
696
697  # mails that make it to the end of the script are passed on to
698  # the internal filtering engine. If the internal rules don't say
699  # otherwise, the mails end up in the default inbox.
700  #-8<----------------------------------------------------
701
702
703 =head1 BUGS
704
705 =over 4
706
707 =item *
708
709 Do B<not> use this plugin together with other filtering plugins,
710 especially the B<Spamassassin> and B<ClamAV> plugins. They are
711 registered on the same hook and the order in which the plugins
712 are executed is not guaranteed.
713
714 =item *
715
716 The filter script is not (yet) updated automatically when a
717 folder gets renamed. The same applies for folder names in
718 addressbook user attributes.
719
720 =item *
721
722 This plugin has only be tested with POP3 accounts. If you have
723 experiences with IMAP or newsgroup accounts, drop me a message.
724
725 =item *
726
727 Warning during compile time:
728
729  *** Warning: Linking the shared library perl_plugin.la against the
730  *** static library
731  /usr/lib/perl5/5.8.3/i586-linux-thread-multi/auto/DynaLoader/DynaLoader.a
732  is not portable!
733
734 Ideas to solve this one are welcome :-)
735
736 =back
737
738 Please report comments, suggestions and bugreports to the address
739 given in the L</AUTHOR> section of this document.
740
741
742 =head1 LICENSE and (no) WARRANTY
743
744 This program is free software; you can redistribute it and/or
745 modify it under the terms of the GNU General Public
746 License as published by the Free Software Foundation;
747 either version 3 of the License, or (at your option) any later
748 version.
749
750 This program is distributed in the hope that it will be useful,
751 but WITHOUT ANY WARRANTY; without even the implied warranty of
752 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
753 GNU General Public License for more details.
754
755 You should have received a copy of the GNU General Public License
756 along with this program. If not, see http://www.gnu.org/licenses/.
757
758 =head1 SEE ALSO
759
760 claws-mail(1), perl(1)
761
762
763 =head1 AUTHOR
764
765 Holger Berndt  <berndth@gmx.de>
766
767 =cut