cm-break.pl 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #!/usr/bin/perl
  2. use 5.14.1;
  3. use warnings;
  4. our $VERSION = "1.05 - 2018-10-08";
  5. our $cmd = $0 =~ s{.*/}{}r;
  6. sub usage {
  7. my $err = shift and select STDERR;
  8. say "usage: $cmd file ...";
  9. exit $err;
  10. } # usage
  11. use Date::Parse;
  12. use Getopt::Long;
  13. GetOptions (
  14. "help|?" => sub { usage (0); },
  15. "V|version" => sub { say "$cmd [$VERSION]"; exit 0; },
  16. ) or usage (1);
  17. my %f;
  18. foreach my $fn (@ARGV) {
  19. open my $fh, "<", $fn or die "$fn: $!\n";
  20. my ($hdr, $body) = split m/(?<=\n)(?=\r?\n)/ => do { local $/; <$fh> }, 2;
  21. close $fh;
  22. $hdr && $hdr =~ m/\b(?:In-Reply-To|References)\b/i or next;
  23. my ($mid) = $hdr =~ m{^Message-Id: (?:[\x20\t]*\n)?[\x20\t]+ (\S.*)}xmi;
  24. my ($dte) = $hdr =~ m{^Date: (?:[\x20\t]*\n)?[\x20\t]+ (\S.*)}xmi;
  25. my ($irt) = $hdr =~ m{^In-Reply-To: (?:[\x20\t]*\n)?[\x20\t]+ (\S.*)}xmi;
  26. my ($ref) = $hdr =~ m{^References: (?:[\x20\t]*\n)?[\x20\t]+ (\S.*)}xmi;
  27. my $stamp = str2time ($dte) or die $dte;
  28. my $date = $stamp ? do {
  29. my @d = localtime $stamp;
  30. sprintf "%4d-%02d-%02d %02d:%02d:%02d", $d[5] + 1900, ++$d[4], @d[3,2,1,0];
  31. } : "-";
  32. #printf "%12s %-20s %s\n", $stamp // "-", $date, $rcv;
  33. $f{$fn} = {
  34. msg_id => $mid,
  35. refs => $ref,
  36. irt => $irt,
  37. date => $dte,
  38. stamp => $stamp,
  39. sdate => $date,
  40. hdr => $hdr,
  41. body => $body,
  42. };
  43. }
  44. foreach my $fn (sort keys %f) {
  45. my $c = 0;
  46. my $f = $f{$fn};
  47. if ($f->{refs}) {
  48. $c++;
  49. $f->{hdr} =~ s{\nReferences:.*(?:\n\s+.*)*+}{}ig;
  50. }
  51. if ($f->{irt}) {
  52. $c++;
  53. $f->{hdr} =~ s{\nIn-Reply-To:.*(?:\n\s+.*)*+}{}ig;
  54. }
  55. $c or next; # No changes required
  56. say "$f->{msg_id} => -";
  57. my @t = stat $fn;
  58. open my $fh, ">", $fn or die "$fn: $!\n";
  59. print $fh $f->{hdr}, $f->{body};
  60. close $fh or die "$fn: $!\n";
  61. utime $t[8], $t[9], $fn;
  62. }
  63. __END__
  64. =head1 NAME
  65. cm-break.pl - remove mail from thread
  66. =head1 SYNOPSIS
  67. cm-break.pl ~/Mail/inbox/23 ~/Mail/inbox/45 ...
  68. =head1 DESCRIPTION
  69. This script should be called from within Claws-Mail as an action
  70. Define an action as
  71. Menu name: Unthread (break threading)
  72. Command: cm-break.pl %F
  73. Then select from the message list all files that should be un-threaded
  74. Then invoke the action
  75. All of those mails will be modified (if needed): their C<In-Reply-To:>
  76. and C<References:> header tags are removed from the header.
  77. =head1 SEE ALSO
  78. L<Date::Parse>, L<Claws Mail|http://www.claws-mail.org>
  79. cm-reparent.pl
  80. =head1 AUTHOR
  81. H.Merijn Brand <h.m.brand@xs4all.nl>
  82. =head1 COPYRIGHT AND LICENSE
  83. Copyright (C) 2018-2018 H.Merijn Brand. All rights reserved.
  84. This library is free software; you can redistribute and/or modify it under
  85. the same terms as Perl itself.
  86. See the L<Artistic license|http://dev.perl.org/licenses/artistic.html>.
  87. =cut