]> git.proxmox.com Git - pmg-api.git/blob - PMG/RuleDB/Remove.pm
add more ruledb objects
[pmg-api.git] / PMG / RuleDB / Remove.pm
1 package PMG::RuleDB::Remove;
2
3 use strict;
4 use warnings;
5 use Carp;
6 use DBI;
7 use Digest::SHA;
8 use MIME::Words;
9 use MIME::Entity;
10 use Encode;
11
12 use PVE::SafeSyslog;
13
14 use PMG::Utils;
15 use PMG::ModGroup;
16 use PMG::RuleDB::Object;
17
18 use base qw(PMG::RuleDB::Object);
19
20 sub otype {
21 return 4007;
22 }
23
24 sub otype_text {
25 return 'Remove attachments';
26 }
27
28 sub oclass {
29 return 'action';
30 }
31
32 sub oicon {
33 return 'remove.gif';
34 }
35
36 sub oinfo {
37 return 'Remove attachments';
38 }
39
40 sub oisedit {
41 return 1;
42 }
43
44 sub final {
45 return 0;
46 }
47
48 sub priority {
49 return 40;
50 }
51
52 sub new {
53 my ($type, $all, $text, $ogroup) = @_;
54
55 my $class = ref($type) || $type;
56
57 $all = 0 if !defined ($all);
58
59 my $self = $class->SUPER::new(otype(), $ogroup);
60
61 $self->{all} = $all;
62 $self->{text} = $text;
63
64 return $self;
65 }
66
67 sub load_attr {
68 my ($type, $ruledb, $id, $ogroup, $value) = @_;
69
70 my $class = ref($type) || $type;
71
72 defined ($value) || croak "undefined value: ERROR";
73
74 my $obj;
75
76 if ($value =~ m/^([01])(\:(.*))?$/s) {
77 $obj = $class->new($1, $3, $ogroup);
78 } else {
79 $obj = $class->new(0, undef, $ogroup);
80 }
81
82 $obj->{id} = $id;
83
84 $obj->{digest} = Digest::SHA::sha1_hex($id, $value, $ogroup);
85
86 return $obj;
87 }
88
89 sub save {
90 my ($self, $ruledb) = @_;
91
92 defined($self->{ogroup}) || croak "undefined ogroup: ERROR";
93
94 my $value = $self->{all} ? '1' : '0';
95
96 if ($self->{text}) {
97 $value .= ":$self->{text}";
98 }
99
100 if (defined ($self->{id})) {
101 # update
102
103 $ruledb->{dbh}->do(
104 "UPDATE Object SET Value = ? WHERE ID = ?",
105 undef, $value, $self->{id});
106
107 } else {
108 # insert
109
110 my $sth = $ruledb->{dbh}->prepare(
111 "INSERT INTO Object (Objectgroup_ID, ObjectType, Value) " .
112 "VALUES (?, ?, ?);");
113
114 $sth->execute($self->ogroup, $self->otype, $value);
115
116 $self->{id} = PMG::Utils::lastid($ruledb->{dbh}, 'object_id_seq');
117 }
118
119 return $self->{id};
120 }
121
122 sub delete_marked_parts {
123 my ($self, $queue, $entity, $html, $rtype, $marks) = @_;
124
125 my $nparts = [];
126
127 my $pn = $entity->parts;
128 for (my $i = 0; $i < $pn; $i++) {
129 my $part = $entity->parts($i);
130
131 my ($id, $found);
132
133 if ($id = $part->head->mime_attr('x-proxmox-tmp-aid')) {
134 chomp $id;
135
136 if ($self->{all}) {
137 my $ctype_part = $part->head->mime_type;
138 if (!($i == 0 && $ctype_part =~ m|text/.*|i)) {
139 $found = 1;
140 }
141 } else {
142 foreach my $m (@$marks) {
143 $found = 1 if $m eq $id;
144 }
145 }
146
147 }
148
149 if ($found) {
150
151 my $on = PMG::Utils::extract_filename($part->head) || '';
152
153 my $text = PMG::Utils::subst_values($html, { FILENAME => $on } );
154
155 my $fname = "REMOVED_ATTACHMENT_$id." . ($rtype eq "text/html" ? "html" : "txt");
156
157 my $ent = MIME::Entity->build(
158 Type => $rtype,
159 Charset => 'UTF-8',
160 Encoding => "quoted-printable",
161 Filename => $fname,
162 Disposition => "attachment",
163 Data => encode('UTF-8', $text));
164
165 push (@$nparts, $ent);
166
167 syslog ('info', "%s: removed attachment $id ('%s')",
168 $queue->{logid}, $on);
169
170 } else {
171 $self->delete_marked_parts($queue, $part, $html, $rtype, $marks);
172 push (@$nparts, $part);
173 }
174 }
175
176 $entity->parts ($nparts);
177 }
178
179 sub execute {
180 my ($self, $queue, $ruledb, $mod_group, $targets,
181 $msginfo, $vars, $marks) = @_;
182
183 if (!$self->{all} && ($#$marks == -1)) {
184 # no marks
185 return;
186 }
187
188 my $subgroups = $mod_group->subgroups ($targets);
189
190 my $html = PMG::Utils::subst_values($self->{text}, $vars);
191
192 $html = "This attachment was removed: __FILENAME__\n" if !$html;
193
194 my $rtype = "text/plain";
195
196 if ($html =~ m/\<\w+\>/s) {
197 $rtype = "text/html";
198 }
199
200 foreach my $ta (@$subgroups) {
201 my ($tg, $entity) = (@$ta[0], @$ta[1]);
202
203 # handle singlepart mails
204 my $ctype = $entity->head->mime_type;
205 if (!$entity->is_multipart && (!$self->{all} || $ctype !~ m|text/.*|i)) {
206 $entity->make_multipart();
207 my $first_part = $entity->parts(0);
208 $first_part->head->mime_attr('x-proxmox-tmp-aid' => $entity->head->mime_attr('x-proxmox-tmp-aid'));
209 $entity->head->delete('x-proxmox-tmp-aid');
210 }
211
212 $self->delete_marked_parts($queue, $entity, $html, $rtype, $marks);
213
214 if ($msginfo->{testmode}) {
215 $entity->head->mime_attr('Content-type.boundary' => '------=_TEST123456') if $entity->is_multipart;
216 }
217 }
218 }
219
220 sub short_desc {
221 my $self = shift;
222
223 if ($self->{all}) {
224 return "remove all attachments";
225 } else {
226 return "remove matching attachments";
227 }
228 }
229
230
231 1;
232 __END__
233
234 =head1 PMG::RuleDB::Remove
235
236 Remove attachments.