Merge lp:~therp-nl/server-env-tools/7.0-fetchmail_attach_from_folder into lp:~server-env-tools-core-editors/server-env-tools/7.0
- 7.0-fetchmail_attach_from_folder
- Merge into 7.0
Proposed by
Holger Brunn (Therp)
Status: | Merged |
---|---|
Merged at revision: | 74 |
Proposed branch: | lp:~therp-nl/server-env-tools/7.0-fetchmail_attach_from_folder |
Merge into: | lp:~server-env-tools-core-editors/server-env-tools/7.0 |
Diff against target: |
1019 lines (+939/-0) 15 files modified
fetchmail_attach_from_folder/__init__.py (+25/-0) fetchmail_attach_from_folder/__openerp__.py (+46/-0) fetchmail_attach_from_folder/match_algorithm/__init__.py (+26/-0) fetchmail_attach_from_folder/match_algorithm/base.py (+43/-0) fetchmail_attach_from_folder/match_algorithm/email_domain.py (+44/-0) fetchmail_attach_from_folder/match_algorithm/email_exact.py (+56/-0) fetchmail_attach_from_folder/match_algorithm/openerp_standard.py (+51/-0) fetchmail_attach_from_folder/model/__init__.py (+24/-0) fetchmail_attach_from_folder/model/fetchmail_server.py (+280/-0) fetchmail_attach_from_folder/model/fetchmail_server_folder.py (+120/-0) fetchmail_attach_from_folder/security/ir.model.access.csv (+2/-0) fetchmail_attach_from_folder/view/fetchmail_server.xml (+56/-0) fetchmail_attach_from_folder/wizard/__init__.py (+23/-0) fetchmail_attach_from_folder/wizard/attach_mail_manually.py (+114/-0) fetchmail_attach_from_folder/wizard/attach_mail_manually.xml (+29/-0) |
To merge this branch: | bzr merge lp:~therp-nl/server-env-tools/7.0-fetchmail_attach_from_folder |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stefan Rijnhart (Opener) | code review | Approve | |
Ronald Portier (Therp) (community) | test | Approve | |
Holger Brunn (Therp) | Needs Resubmitting | ||
Nicolas JEUDY (community) | code review and test install | Needs Fixing | |
Review via email: mp+201970@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote : | # |
review:
Needs Fixing
- 55. By Holger Brunn (Therp)
-
[IMP] remove deprecated type field for views
Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote : | # |
thanks!
Revision history for this message
Nicolas JEUDY (njeudy) wrote : | # |
hello
fetchmail_
What are this line for ?
Whithout those lines, module is installed correctly on V7 and futur trunk. I will test with an imap account tomorrow
review:
Needs Fixing
(code review and test install)
- 56. By Holger Brunn (Therp)
-
[IMP] adjust view definitions to 7.0
[FIX] use mail_thread.message_ parse in wizard
Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote : | # |
Thanks Nicholas, those were leftovers from the 6.1 version
Revision history for this message
Holger Brunn (Therp) (hbrunn) wrote : | # |
forgot to resubmit
review:
Needs Resubmitting
Revision history for this message
Ronald Portier (Therp) (rportier1962) wrote : | # |
Tested code before, both on 6.1 and 7.0 and is working really well.
LGTM on the code as well.
review:
Approve
(test)
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) : | # |
review:
Approve
(code review)
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote : | # |
Seeing that Nicolas' comments have been honoured months ago, I'm merging this.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'fetchmail_attach_from_folder' |
2 | === added file 'fetchmail_attach_from_folder/__init__.py' |
3 | --- fetchmail_attach_from_folder/__init__.py 1970-01-01 00:00:00 +0000 |
4 | +++ fetchmail_attach_from_folder/__init__.py 2014-02-03 09:33:52 +0000 |
5 | @@ -0,0 +1,25 @@ |
6 | +# -*- encoding: utf-8 -*- |
7 | +############################################################################## |
8 | +# |
9 | +# OpenERP, Open Source Management Solution |
10 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
11 | +# All Rights Reserved |
12 | +# |
13 | +# This program is free software: you can redistribute it and/or modify |
14 | +# it under the terms of the GNU Affero General Public License as |
15 | +# published by the Free Software Foundation, either version 3 of the |
16 | +# License, or (at your option) any later version. |
17 | +# |
18 | +# This program is distributed in the hope that it will be useful, |
19 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | +# GNU Affero General Public License for more details. |
22 | +# |
23 | +# You should have received a copy of the GNU Affero General Public License |
24 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
25 | +# |
26 | +############################################################################## |
27 | + |
28 | +import match_algorithm |
29 | +import model |
30 | +import wizard |
31 | |
32 | === added file 'fetchmail_attach_from_folder/__openerp__.py' |
33 | --- fetchmail_attach_from_folder/__openerp__.py 1970-01-01 00:00:00 +0000 |
34 | +++ fetchmail_attach_from_folder/__openerp__.py 2014-02-03 09:33:52 +0000 |
35 | @@ -0,0 +1,46 @@ |
36 | +# -*- encoding: utf-8 -*- |
37 | +############################################################################## |
38 | +# |
39 | +# OpenERP, Open Source Management Solution |
40 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
41 | +# All Rights Reserved |
42 | +# |
43 | +# This program is free software: you can redistribute it and/or modify |
44 | +# it under the terms of the GNU Affero General Public License as |
45 | +# published by the Free Software Foundation, either version 3 of the |
46 | +# License, or (at your option) any later version. |
47 | +# |
48 | +# This program is distributed in the hope that it will be useful, |
49 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
50 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
51 | +# GNU Affero General Public License for more details. |
52 | +# |
53 | +# You should have received a copy of the GNU Affero General Public License |
54 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
55 | +# |
56 | +############################################################################## |
57 | + |
58 | +{ |
59 | + 'name': 'Attach mails in an IMAP folder to existing objects', |
60 | + 'version': '1.0', |
61 | + 'description': """ |
62 | +Adds the possibility to attach emails from a certain IMAP folder to objects, |
63 | +ie partners. Matching is done via several algorithms, ie email address. |
64 | + |
65 | +This gives a simple possibility to archive emails in OpenERP without a mail |
66 | +client integration. |
67 | + """, |
68 | + 'author': 'Therp BV', |
69 | + 'website': 'http://www.therp.nl', |
70 | + "category": "Tools", |
71 | + "depends": ['fetchmail'], |
72 | + 'data': [ |
73 | + 'view/fetchmail_server.xml', |
74 | + 'wizard/attach_mail_manually.xml', |
75 | + 'security/ir.model.access.csv', |
76 | + ], |
77 | + 'js': [], |
78 | + 'installable': True, |
79 | + 'active': False, |
80 | + 'certificate': '', |
81 | +} |
82 | |
83 | === added directory 'fetchmail_attach_from_folder/match_algorithm' |
84 | === added file 'fetchmail_attach_from_folder/match_algorithm/__init__.py' |
85 | --- fetchmail_attach_from_folder/match_algorithm/__init__.py 1970-01-01 00:00:00 +0000 |
86 | +++ fetchmail_attach_from_folder/match_algorithm/__init__.py 2014-02-03 09:33:52 +0000 |
87 | @@ -0,0 +1,26 @@ |
88 | +# -*- encoding: utf-8 -*- |
89 | +############################################################################## |
90 | +# |
91 | +# OpenERP, Open Source Management Solution |
92 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
93 | +# All Rights Reserved |
94 | +# |
95 | +# This program is free software: you can redistribute it and/or modify |
96 | +# it under the terms of the GNU Affero General Public License as |
97 | +# published by the Free Software Foundation, either version 3 of the |
98 | +# License, or (at your option) any later version. |
99 | +# |
100 | +# This program is distributed in the hope that it will be useful, |
101 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
102 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
103 | +# GNU Affero General Public License for more details. |
104 | +# |
105 | +# You should have received a copy of the GNU Affero General Public License |
106 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
107 | +# |
108 | +############################################################################## |
109 | + |
110 | +import base |
111 | +import email_exact |
112 | +import email_domain |
113 | +import openerp_standard |
114 | |
115 | === added file 'fetchmail_attach_from_folder/match_algorithm/base.py' |
116 | --- fetchmail_attach_from_folder/match_algorithm/base.py 1970-01-01 00:00:00 +0000 |
117 | +++ fetchmail_attach_from_folder/match_algorithm/base.py 2014-02-03 09:33:52 +0000 |
118 | @@ -0,0 +1,43 @@ |
119 | +# -*- encoding: utf-8 -*- |
120 | +############################################################################## |
121 | +# |
122 | +# OpenERP, Open Source Management Solution |
123 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
124 | +# All Rights Reserved |
125 | +# |
126 | +# This program is free software: you can redistribute it and/or modify |
127 | +# it under the terms of the GNU Affero General Public License as |
128 | +# published by the Free Software Foundation, either version 3 of the |
129 | +# License, or (at your option) any later version. |
130 | +# |
131 | +# This program is distributed in the hope that it will be useful, |
132 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
133 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
134 | +# GNU Affero General Public License for more details. |
135 | +# |
136 | +# You should have received a copy of the GNU Affero General Public License |
137 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
138 | +# |
139 | +############################################################################## |
140 | + |
141 | +class base(object): |
142 | + name = None |
143 | + '''Name shown to the user''' |
144 | + |
145 | + required_fields = [] |
146 | + '''Fields on fetchmail_server folder that are required for this algorithm''' |
147 | + |
148 | + readonly_fields = [] |
149 | + '''Fields on fetchmail_server folder that are readonly for this algorithm''' |
150 | + |
151 | + |
152 | + def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
153 | + '''Returns ids found for model with mail_message''' |
154 | + return [] |
155 | + |
156 | + def handle_match( |
157 | + self, cr, uid, connection, object_id, folder, |
158 | + mail_message, mail_message_org, msgid, context=None): |
159 | + '''Do whatever it takes to handle a match''' |
160 | + return folder.server_id.attach_mail(connection, object_id, folder, |
161 | + mail_message, msgid) |
162 | |
163 | === added file 'fetchmail_attach_from_folder/match_algorithm/email_domain.py' |
164 | --- fetchmail_attach_from_folder/match_algorithm/email_domain.py 1970-01-01 00:00:00 +0000 |
165 | +++ fetchmail_attach_from_folder/match_algorithm/email_domain.py 2014-02-03 09:33:52 +0000 |
166 | @@ -0,0 +1,44 @@ |
167 | +# -*- encoding: utf-8 -*- |
168 | +############################################################################## |
169 | +# |
170 | +# OpenERP, Open Source Management Solution |
171 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
172 | +# All Rights Reserved |
173 | +# |
174 | +# This program is free software: you can redistribute it and/or modify |
175 | +# it under the terms of the GNU Affero General Public License as |
176 | +# published by the Free Software Foundation, either version 3 of the |
177 | +# License, or (at your option) any later version. |
178 | +# |
179 | +# This program is distributed in the hope that it will be useful, |
180 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
181 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
182 | +# GNU Affero General Public License for more details. |
183 | +# |
184 | +# You should have received a copy of the GNU Affero General Public License |
185 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
186 | +# |
187 | +############################################################################## |
188 | + |
189 | +from email_exact import email_exact |
190 | + |
191 | +class email_domain(email_exact): |
192 | + '''Search objects by domain name of email address. |
193 | + Beware of match_first here, this is most likely to get it wrong (gmail)''' |
194 | + name = 'Domain of email address' |
195 | + |
196 | + def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
197 | + ids = super(email_domain, self).search_matches( |
198 | + cr, uid, conf, mail_message, mail_message_org) |
199 | + if not ids: |
200 | + domains = [] |
201 | + for addr in self._get_mailaddresses(conf, mail_message): |
202 | + domains.append(addr.split('@')[-1]) |
203 | + ids = conf.pool.get(conf.model_id.model).search( |
204 | + cr, uid, |
205 | + self._get_mailaddress_search_domain( |
206 | + conf, mail_message, |
207 | + operator='like', |
208 | + values=['%@'+domain for domain in set(domains)]), |
209 | + order=conf.model_order) |
210 | + return ids |
211 | |
212 | === added file 'fetchmail_attach_from_folder/match_algorithm/email_exact.py' |
213 | --- fetchmail_attach_from_folder/match_algorithm/email_exact.py 1970-01-01 00:00:00 +0000 |
214 | +++ fetchmail_attach_from_folder/match_algorithm/email_exact.py 2014-02-03 09:33:52 +0000 |
215 | @@ -0,0 +1,56 @@ |
216 | +# -*- encoding: utf-8 -*- |
217 | +############################################################################## |
218 | +# |
219 | +# OpenERP, Open Source Management Solution |
220 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
221 | +# All Rights Reserved |
222 | +# |
223 | +# This program is free software: you can redistribute it and/or modify |
224 | +# it under the terms of the GNU Affero General Public License as |
225 | +# published by the Free Software Foundation, either version 3 of the |
226 | +# License, or (at your option) any later version. |
227 | +# |
228 | +# This program is distributed in the hope that it will be useful, |
229 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
230 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
231 | +# GNU Affero General Public License for more details. |
232 | +# |
233 | +# You should have received a copy of the GNU Affero General Public License |
234 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
235 | +# |
236 | +############################################################################## |
237 | + |
238 | +from base import base |
239 | +from openerp.tools.safe_eval import safe_eval |
240 | +from openerp.tools.mail import email_split |
241 | + |
242 | +class email_exact(base): |
243 | + '''Search for exactly the mailadress as noted in the email''' |
244 | + |
245 | + name = 'Exact mailadress' |
246 | + required_fields = ['model_field', 'mail_field'] |
247 | + |
248 | + def _get_mailaddresses(self, conf, mail_message): |
249 | + mailaddresses = [] |
250 | + fields = conf.mail_field.split(',') |
251 | + for field in fields: |
252 | + if field in mail_message: |
253 | + mailaddresses += email_split(mail_message[field]) |
254 | + return [ addr.lower() for addr in mailaddresses ] |
255 | + |
256 | + def _get_mailaddress_search_domain( |
257 | + self, conf, mail_message, operator='=', values=None): |
258 | + mailaddresses = values or self._get_mailaddresses( |
259 | + conf, mail_message) |
260 | + if not mailaddresses: |
261 | + return [(0, '=', 1)] |
262 | + search_domain = ((['|'] * (len(mailaddresses) - 1)) + [ |
263 | + (conf.model_field, operator, addr) for addr in mailaddresses] + |
264 | + safe_eval(conf.domain or '[]')) |
265 | + return search_domain |
266 | + |
267 | + def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
268 | + conf_model = conf.pool.get(conf.model_id.model) |
269 | + search_domain = self._get_mailaddress_search_domain(conf, mail_message) |
270 | + return conf_model.search( |
271 | + cr, uid, search_domain, order=conf.model_order) |
272 | |
273 | === added file 'fetchmail_attach_from_folder/match_algorithm/openerp_standard.py' |
274 | --- fetchmail_attach_from_folder/match_algorithm/openerp_standard.py 1970-01-01 00:00:00 +0000 |
275 | +++ fetchmail_attach_from_folder/match_algorithm/openerp_standard.py 2014-02-03 09:33:52 +0000 |
276 | @@ -0,0 +1,51 @@ |
277 | +# -*- encoding: utf-8 -*- |
278 | +############################################################################## |
279 | +# |
280 | +# OpenERP, Open Source Management Solution |
281 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
282 | +# All Rights Reserved |
283 | +# |
284 | +# This program is free software: you can redistribute it and/or modify |
285 | +# it under the terms of the GNU Affero General Public License as |
286 | +# published by the Free Software Foundation, either version 3 of the |
287 | +# License, or (at your option) any later version. |
288 | +# |
289 | +# This program is distributed in the hope that it will be useful, |
290 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
291 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
292 | +# GNU Affero General Public License for more details. |
293 | +# |
294 | +# You should have received a copy of the GNU Affero General Public License |
295 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
296 | +# |
297 | +############################################################################## |
298 | + |
299 | +from base import base |
300 | +from openerp.tools.safe_eval import safe_eval |
301 | + |
302 | +class openerp_standard(base): |
303 | + '''No search at all. Use OpenERP's standard mechanism to attach mails to |
304 | + mail.thread objects. Note that this algorithm always matches.''' |
305 | + |
306 | + name = 'OpenERP standard' |
307 | + readonly_fields = ['model_field', 'mail_field', 'match_first', 'domain', |
308 | + 'model_order', 'flag_nonmatching'] |
309 | + |
310 | + def search_matches(self, cr, uid, conf, mail_message, mail_message_org): |
311 | + '''Always match. Duplicates will be fished out by message_id''' |
312 | + return [True] |
313 | + |
314 | + def handle_match( |
315 | + self, cr, uid, connection, object_id, folder, |
316 | + mail_message, mail_message_org, msgid, context): |
317 | + result = folder.pool.get('mail.thread').message_process( |
318 | + cr, uid, |
319 | + folder.model_id.model, mail_message_org, |
320 | + save_original=folder.server_id.original, |
321 | + strip_attachments=(not folder.server_id.attach), |
322 | + context=context) |
323 | + |
324 | + if folder.delete_matching: |
325 | + connection.store(msgid, '+FLAGS', '\\DELETED') |
326 | + |
327 | + return [result] |
328 | |
329 | === added directory 'fetchmail_attach_from_folder/model' |
330 | === added file 'fetchmail_attach_from_folder/model/__init__.py' |
331 | --- fetchmail_attach_from_folder/model/__init__.py 1970-01-01 00:00:00 +0000 |
332 | +++ fetchmail_attach_from_folder/model/__init__.py 2014-02-03 09:33:52 +0000 |
333 | @@ -0,0 +1,24 @@ |
334 | +# -*- encoding: utf-8 -*- |
335 | +############################################################################## |
336 | +# |
337 | +# OpenERP, Open Source Management Solution |
338 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
339 | +# All Rights Reserved |
340 | +# |
341 | +# This program is free software: you can redistribute it and/or modify |
342 | +# it under the terms of the GNU Affero General Public License as |
343 | +# published by the Free Software Foundation, either version 3 of the |
344 | +# License, or (at your option) any later version. |
345 | +# |
346 | +# This program is distributed in the hope that it will be useful, |
347 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
348 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
349 | +# GNU Affero General Public License for more details. |
350 | +# |
351 | +# You should have received a copy of the GNU Affero General Public License |
352 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
353 | +# |
354 | +############################################################################## |
355 | + |
356 | +import fetchmail_server |
357 | +import fetchmail_server_folder |
358 | |
359 | === added file 'fetchmail_attach_from_folder/model/fetchmail_server.py' |
360 | --- fetchmail_attach_from_folder/model/fetchmail_server.py 1970-01-01 00:00:00 +0000 |
361 | +++ fetchmail_attach_from_folder/model/fetchmail_server.py 2014-02-03 09:33:52 +0000 |
362 | @@ -0,0 +1,280 @@ |
363 | +# -*- encoding: utf-8 -*- |
364 | +############################################################################## |
365 | +# |
366 | +# OpenERP, Open Source Management Solution |
367 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
368 | +# All Rights Reserved |
369 | +# |
370 | +# This program is free software: you can redistribute it and/or modify |
371 | +# it under the terms of the GNU Affero General Public License as |
372 | +# published by the Free Software Foundation, either version 3 of the |
373 | +# License, or (at your option) any later version. |
374 | +# |
375 | +# This program is distributed in the hope that it will be useful, |
376 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
377 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
378 | +# GNU Affero General Public License for more details. |
379 | +# |
380 | +# You should have received a copy of the GNU Affero General Public License |
381 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
382 | +# |
383 | +############################################################################## |
384 | + |
385 | +import base64 |
386 | +import simplejson |
387 | +from lxml import etree |
388 | +from openerp.osv.orm import Model, except_orm, browse_null |
389 | +from openerp.tools.translate import _ |
390 | +from openerp.osv import fields |
391 | +from openerp.addons.fetchmail.fetchmail import _logger as logger |
392 | +from openerp.tools.misc import UnquoteEvalContext |
393 | +from openerp.tools.safe_eval import safe_eval |
394 | + |
395 | + |
396 | +class fetchmail_server(Model): |
397 | + _inherit = 'fetchmail.server' |
398 | + |
399 | + _columns = { |
400 | + 'folder_ids': fields.one2many( |
401 | + 'fetchmail.server.folder', 'server_id', 'Folders'), |
402 | + } |
403 | + |
404 | + _defaults = { |
405 | + 'type': 'imap', |
406 | + } |
407 | + |
408 | + def __init__(self, pool, cr): |
409 | + self._columns['object_id'].required = False |
410 | + return super(fetchmail_server, self).__init__(pool, cr) |
411 | + |
412 | + def onchange_server_type( |
413 | + self, cr, uid, ids, server_type=False, ssl=False, |
414 | + object_id=False): |
415 | + retval = super( |
416 | + fetchmail_server, self).onchange_server_type(cr, uid, |
417 | + ids, server_type, ssl, |
418 | + object_id) |
419 | + retval['value']['state'] = 'draft' |
420 | + return retval |
421 | + |
422 | + def fetch_mail(self, cr, uid, ids, context=None): |
423 | + if context is None: |
424 | + context = {} |
425 | + |
426 | + check_original = [] |
427 | + |
428 | + for this in self.browse(cr, uid, ids, context): |
429 | + if this.object_id: |
430 | + check_original.append(this.id) |
431 | + |
432 | + context.update( |
433 | + { |
434 | + 'fetchmail_server_id': this.id, |
435 | + 'server_type': this.type |
436 | + }) |
437 | + |
438 | + connection = this.connect() |
439 | + for folder in this.folder_ids: |
440 | + this.handle_folder(connection, folder) |
441 | + |
442 | + connection.close() |
443 | + |
444 | + return super(fetchmail_server, self).fetch_mail( |
445 | + cr, uid, check_original, context) |
446 | + |
447 | + def handle_folder(self, cr, uid, ids, connection, folder, context=None): |
448 | + '''Return ids of objects matched''' |
449 | + |
450 | + matched_object_ids = [] |
451 | + |
452 | + for this in self.browse(cr, uid, ids, context=context): |
453 | + logger.info('start checking for emails in %s server %s', |
454 | + folder.path, this.name) |
455 | + |
456 | + match_algorithm = folder.get_algorithm() |
457 | + |
458 | + if connection.select(folder.path)[0] != 'OK': |
459 | + logger.error( |
460 | + 'Could not open mailbox %s on %s' % ( |
461 | + folder.path, this.server)) |
462 | + connection.select() |
463 | + continue |
464 | + result, msgids = this.get_msgids(connection) |
465 | + if result != 'OK': |
466 | + logger.error( |
467 | + 'Could not search mailbox %s on %s' % ( |
468 | + folder.path, this.server)) |
469 | + continue |
470 | + |
471 | + for msgid in msgids[0].split(): |
472 | + matched_object_ids += this.apply_matching( |
473 | + connection, folder, msgid, match_algorithm) |
474 | + |
475 | + logger.info('finished checking for emails in %s server %s', |
476 | + folder.path, this.name) |
477 | + |
478 | + return matched_object_ids |
479 | + |
480 | + def get_msgids(self, cr, uid, ids, connection, context=None): |
481 | + '''Return imap ids of messages to process''' |
482 | + return connection.search(None, 'UNDELETED') |
483 | + |
484 | + def apply_matching(self, cr, uid, ids, connection, folder, msgid, |
485 | + match_algorithm, context=None): |
486 | + '''Return ids of objects matched''' |
487 | + |
488 | + matched_object_ids = [] |
489 | + |
490 | + for this in self.browse(cr, uid, ids, context=context): |
491 | + result, msgdata = connection.fetch(msgid, '(RFC822)') |
492 | + |
493 | + if result != 'OK': |
494 | + logger.error( |
495 | + 'Could not fetch %s in %s on %s' % ( |
496 | + msgid, folder.path, this.server)) |
497 | + continue |
498 | + |
499 | + mail_message = self.pool.get('mail.thread').message_parse( |
500 | + cr, uid, msgdata[0][1], save_original=this.original, |
501 | + context=context) |
502 | + |
503 | + if self.pool.get('mail.message').search(cr, uid, [ |
504 | + ('message_id', '=', mail_message['message_id'])]): |
505 | + continue |
506 | + |
507 | + found_ids = match_algorithm.search_matches( |
508 | + cr, uid, folder, |
509 | + mail_message, msgdata[0][1]) |
510 | + |
511 | + if found_ids and (len(found_ids) == 1 or |
512 | + folder.match_first): |
513 | + try: |
514 | + cr.execute('savepoint apply_matching') |
515 | + match_algorithm.handle_match( |
516 | + cr, uid, connection, |
517 | + found_ids[0], folder, mail_message, |
518 | + msgdata[0][1], msgid, context) |
519 | + cr.execute('release savepoint apply_matching') |
520 | + matched_object_ids += found_ids[:1] |
521 | + except Exception, e: |
522 | + cr.execute('rollback to savepoint apply_matching') |
523 | + logger.exception( |
524 | + "Failed to fetch mail %s from %s", |
525 | + msgid, this.name) |
526 | + elif folder.flag_nonmatching: |
527 | + connection.store(msgid, '+FLAGS', '\\FLAGGED') |
528 | + |
529 | + return matched_object_ids |
530 | + |
531 | + def attach_mail( |
532 | + self, cr, uid, ids, connection, object_id, folder, |
533 | + mail_message, msgid, context=None): |
534 | + '''Return ids of messages created''' |
535 | + |
536 | + mail_message_ids = [] |
537 | + |
538 | + for this in self.browse(cr, uid, ids, context): |
539 | + partner_id = None |
540 | + if folder.model_id.model == 'res.partner': |
541 | + partner_id = object_id |
542 | + if 'partner_id' in self.pool.get(folder.model_id.model)._columns: |
543 | + partner_id = self.pool.get( |
544 | + folder.model_id.model).browse( |
545 | + cr, uid, object_id, context |
546 | + ).partner_id.id |
547 | + |
548 | + attachments=[] |
549 | + if this.attach and mail_message.get('attachments'): |
550 | + for attachment in mail_message['attachments']: |
551 | + fname, fcontent = attachment |
552 | + if isinstance(fcontent, unicode): |
553 | + fcontent = fcontent.encode('utf-8') |
554 | + data_attach = { |
555 | + 'name': fname, |
556 | + 'datas': base64.b64encode(str(fcontent)), |
557 | + 'datas_fname': fname, |
558 | + 'description': _('Mail attachment'), |
559 | + 'res_model': folder.model_id.model, |
560 | + 'res_id': object_id, |
561 | + } |
562 | + attachments.append( |
563 | + self.pool.get('ir.attachment').create( |
564 | + cr, uid, data_attach, context=context)) |
565 | + |
566 | + mail_message_ids.append( |
567 | + self.pool.get('mail.message').create( |
568 | + cr, uid, |
569 | + { |
570 | + 'author_id': partner_id, |
571 | + 'model': folder.model_id.model, |
572 | + 'res_id': object_id, |
573 | + 'type': 'email', |
574 | + 'body': mail_message.get('body'), |
575 | + 'subject': mail_message.get('subject'), |
576 | + 'email_from': mail_message.get('from'), |
577 | + 'date': mail_message.get('date'), |
578 | + 'message_id': mail_message.get('message_id'), |
579 | + 'attachment_ids': [(6, 0, attachments)], |
580 | + }, |
581 | + context)) |
582 | + |
583 | + if folder.delete_matching: |
584 | + connection.store(msgid, '+FLAGS', '\\DELETED') |
585 | + return mail_message_ids |
586 | + |
587 | + def button_confirm_login(self, cr, uid, ids, context=None): |
588 | + retval = super(fetchmail_server, self).button_confirm_login(cr, uid, |
589 | + ids, |
590 | + context) |
591 | + |
592 | + for this in self.browse(cr, uid, ids, context): |
593 | + this.write({'state': 'draft'}) |
594 | + connection = this.connect() |
595 | + connection.select() |
596 | + for folder in this.folder_ids: |
597 | + if connection.select(folder.path)[0] != 'OK': |
598 | + raise except_orm( |
599 | + _('Error'), _('Mailbox %s not found!') % |
600 | + folder.path) |
601 | + connection.close() |
602 | + this.write({'state': 'done'}) |
603 | + |
604 | + return retval |
605 | + |
606 | + def fields_view_get(self, cr, user, view_id=None, view_type='form', |
607 | + context=None, toolbar=False, submenu=False): |
608 | + result = super(fetchmail_server, self).fields_view_get( |
609 | + cr, user, view_id, view_type, context, toolbar, submenu) |
610 | + |
611 | + if view_type == 'form': |
612 | + view = etree.fromstring( |
613 | + result['fields']['folder_ids']['views']['form']['arch']) |
614 | + modifiers = {} |
615 | + docstr = '' |
616 | + for algorithm in self.pool.get('fetchmail.server.folder')\ |
617 | + ._get_match_algorithms().itervalues(): |
618 | + for modifier in ['required', 'readonly']: |
619 | + for field in getattr(algorithm, modifier + '_fields'): |
620 | + modifiers.setdefault(field, {}) |
621 | + modifiers[field].setdefault(modifier, []) |
622 | + if modifiers[field][modifier]: |
623 | + modifiers[field][modifier].insert(0, '|') |
624 | + modifiers[field][modifier].append( |
625 | + ("match_algorithm", "==", algorithm.__name__)) |
626 | + docstr += _(algorithm.name) + '\n' + _(algorithm.__doc__) + \ |
627 | + '\n\n' |
628 | + |
629 | + for field in view: |
630 | + if field.tag == 'field' and field.get('name') in modifiers: |
631 | + field.set('modifiers', simplejson.dumps( |
632 | + dict( |
633 | + eval(field.attrib['modifiers'], |
634 | + UnquoteEvalContext({})), |
635 | + **modifiers[field.attrib['name']]))) |
636 | + if (field.tag == 'field' and |
637 | + field.get('name') == 'match_algorithm'): |
638 | + field.set('help', docstr) |
639 | + result['fields']['folder_ids']['views']['form']['arch'] = \ |
640 | + etree.tostring(view) |
641 | + |
642 | + return result |
643 | |
644 | === added file 'fetchmail_attach_from_folder/model/fetchmail_server_folder.py' |
645 | --- fetchmail_attach_from_folder/model/fetchmail_server_folder.py 1970-01-01 00:00:00 +0000 |
646 | +++ fetchmail_attach_from_folder/model/fetchmail_server_folder.py 2014-02-03 09:33:52 +0000 |
647 | @@ -0,0 +1,120 @@ |
648 | +# -*- encoding: utf-8 -*- |
649 | +############################################################################## |
650 | +# |
651 | +# OpenERP, Open Source Management Solution |
652 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
653 | +# All Rights Reserved |
654 | +# |
655 | +# This program is free software: you can redistribute it and/or modify |
656 | +# it under the terms of the GNU Affero General Public License as |
657 | +# published by the Free Software Foundation, either version 3 of the |
658 | +# License, or (at your option) any later version. |
659 | +# |
660 | +# This program is distributed in the hope that it will be useful, |
661 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
662 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
663 | +# GNU Affero General Public License for more details. |
664 | +# |
665 | +# You should have received a copy of the GNU Affero General Public License |
666 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
667 | +# |
668 | +######################################################################## |
669 | + |
670 | +from openerp.osv import fields |
671 | +from openerp.osv.orm import Model |
672 | +from .. import match_algorithm |
673 | + |
674 | + |
675 | +class fetchmail_server_folder(Model): |
676 | + _name = 'fetchmail.server.folder' |
677 | + _rec_name = 'path' |
678 | + |
679 | + def _get_match_algorithms(self): |
680 | + def get_all_subclasses(cls): |
681 | + return cls.__subclasses__() + [subsub |
682 | + for sub in cls.__subclasses__() |
683 | + for subsub in get_all_subclasses(sub)] |
684 | + return dict([(cls.__name__, cls) for cls in get_all_subclasses( |
685 | + match_algorithm.base.base)]) |
686 | + |
687 | + def _get_match_algorithms_sel(self, cr, uid, context=None): |
688 | + algorithms = [] |
689 | + for cls in self._get_match_algorithms().itervalues(): |
690 | + algorithms.append((cls.__name__, cls.name)) |
691 | + algorithms.sort() |
692 | + return algorithms |
693 | + |
694 | + _columns = { |
695 | + 'sequence': fields.integer('Sequence'), |
696 | + 'path': fields.char( |
697 | + 'Path', size=256, help='The path to your mail ' |
698 | + "folder. Typically would be something like 'INBOX.myfolder'", |
699 | + required=True), |
700 | + 'model_id': fields.many2one( |
701 | + 'ir.model', 'Model', required=True, |
702 | + help='The model to attach emails to'), |
703 | + 'model_field': fields.char( |
704 | + 'Field (model)', size=128, |
705 | + help='The field in your model that contains the field to match ' |
706 | + 'against.\n' |
707 | + 'Examples:\n' |
708 | + "'email' if your model is res.partner, or " |
709 | + "'partner_id.email' if you're matching sale orders"), |
710 | + 'model_order': fields.char( |
711 | + 'Order (model)', size=128, |
712 | + help='Fields to order by, this mostly useful in conjunction ' |
713 | + "with 'Use 1st match'"), |
714 | + 'match_algorithm': fields.selection( |
715 | + _get_match_algorithms_sel, |
716 | + 'Match algorithm', required=True, translate=True, |
717 | + help='The algorithm used to determine which object an email ' |
718 | + 'matches.'), |
719 | + 'mail_field': fields.char( |
720 | + 'Field (email)', size=128, |
721 | + help='The field in the email used for matching. Typically ' |
722 | + "this is 'to' or 'from'"), |
723 | + 'server_id': fields.many2one('fetchmail.server', 'Server'), |
724 | + 'delete_matching': fields.boolean( |
725 | + 'Delete matches', |
726 | + help='Delete matched emails from server'), |
727 | + 'flag_nonmatching': fields.boolean( |
728 | + 'Flag nonmatching', |
729 | + help="Flag emails in the server that don't match any object " |
730 | + 'in OpenERP'), |
731 | + 'match_first': fields.boolean( |
732 | + 'Use 1st match', |
733 | + help='If there are multiple matches, use the first one. If ' |
734 | + 'not checked, multiple matches count as no match at all'), |
735 | + 'domain': fields.char( |
736 | + 'Domain', size=128, help='Fill in a search ' |
737 | + 'filter to narrow down objects to match'), |
738 | + 'msg_state': fields.selection( |
739 | + [ |
740 | + ('sent', 'Sent'), |
741 | + ('received', 'Received'), |
742 | + ], |
743 | + 'Message state', |
744 | + help='The state messages fetched from this folder should be ' |
745 | + 'assigned in OpenERP'), |
746 | + } |
747 | + |
748 | + _defaults = { |
749 | + 'flag_nonmatching': True, |
750 | + 'msg_state': 'received', |
751 | + } |
752 | + |
753 | + def get_algorithm(self, cr, uid, ids, context=None): |
754 | + for this in self.browse(cr, uid, ids, context): |
755 | + return self._get_match_algorithms()[this.match_algorithm]() |
756 | + |
757 | + def button_attach_mail_manually(self, cr, uid, ids, context=None): |
758 | + for this in self.browse(cr, uid, ids, context): |
759 | + context.update({'default_folder_id': this.id}) |
760 | + return { |
761 | + 'type': 'ir.actions.act_window', |
762 | + 'res_model': 'fetchmail.attach.mail.manually', |
763 | + 'target': 'new', |
764 | + 'context': context, |
765 | + 'view_type': 'form', |
766 | + 'view_mode': 'form', |
767 | + } |
768 | |
769 | === added directory 'fetchmail_attach_from_folder/security' |
770 | === added file 'fetchmail_attach_from_folder/security/ir.model.access.csv' |
771 | --- fetchmail_attach_from_folder/security/ir.model.access.csv 1970-01-01 00:00:00 +0000 |
772 | +++ fetchmail_attach_from_folder/security/ir.model.access.csv 2014-02-03 09:33:52 +0000 |
773 | @@ -0,0 +1,2 @@ |
774 | +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
775 | +access_model_fetchmail_server_folder,fetchmail.server.folder,model_fetchmail_server_folder,base.group_system,1,1,1,1 |
776 | |
777 | === added directory 'fetchmail_attach_from_folder/view' |
778 | === added file 'fetchmail_attach_from_folder/view/fetchmail_server.xml' |
779 | --- fetchmail_attach_from_folder/view/fetchmail_server.xml 1970-01-01 00:00:00 +0000 |
780 | +++ fetchmail_attach_from_folder/view/fetchmail_server.xml 2014-02-03 09:33:52 +0000 |
781 | @@ -0,0 +1,56 @@ |
782 | +<?xml version="1.0" encoding="utf-8"?> |
783 | +<openerp> |
784 | + <data> |
785 | + <record model="ir.ui.view" id="view_email_server_form"> |
786 | + <field name="name">fetchmail.server.form</field> |
787 | + <field name="model">fetchmail.server</field> |
788 | + <field name="inherit_id" ref="fetchmail.view_email_server_form" /> |
789 | + <field name="arch" type="xml"> |
790 | + <data> |
791 | + <field name="object_id" position="attributes"> |
792 | + <attribute name="attrs">{'required': [('type', '!=', 'imap')]}</attribute> |
793 | + </field> |
794 | + <xpath expr="//page[@string='Server & Login']/group/group[3]" position="after"> |
795 | + <group attrs="{'invisible': [('type','!=','imap')]}" string="Folders to monitor"> |
796 | + <field |
797 | + name="folder_ids" |
798 | + nolabel="1" |
799 | + on_change="onchange_server_type(type, is_ssl, object_id)"> |
800 | + <tree> |
801 | + <field name="sequence" invisible="1" /> |
802 | + <field name="path" /> |
803 | + <field name="model_id" /> |
804 | + <field name="model_field" /> |
805 | + <field name="match_algorithm" /> |
806 | + <field name="mail_field" /> |
807 | + </tree> |
808 | + <form version="7.0"> |
809 | + <header> |
810 | + <button type="object" name="button_attach_mail_manually" string="Attach mail manually" icon="gtk-redo" /> |
811 | + </header> |
812 | + <group> |
813 | + <group> |
814 | + <field name="path" /> |
815 | + <field name="model_id" /> |
816 | + <field name="model_field" /> |
817 | + <field name="match_algorithm" /> |
818 | + <field name="mail_field" /> |
819 | + </group> |
820 | + <group> |
821 | + <field name="delete_matching" /> |
822 | + <field name="flag_nonmatching" /> |
823 | + <field name="match_first" /> |
824 | + <field name="msg_state" /> |
825 | + <field name="model_order" attrs="{'readonly': [('match_first','==',False)], 'required': [('match_first','==',True)]}" /> |
826 | + <field name="domain" /> |
827 | + </group> |
828 | + </group> |
829 | + </form> |
830 | + </field> |
831 | + </group> |
832 | + </xpath> |
833 | + </data> |
834 | + </field> |
835 | + </record> |
836 | + </data> |
837 | +</openerp> |
838 | |
839 | === added directory 'fetchmail_attach_from_folder/wizard' |
840 | === added file 'fetchmail_attach_from_folder/wizard/__init__.py' |
841 | --- fetchmail_attach_from_folder/wizard/__init__.py 1970-01-01 00:00:00 +0000 |
842 | +++ fetchmail_attach_from_folder/wizard/__init__.py 2014-02-03 09:33:52 +0000 |
843 | @@ -0,0 +1,23 @@ |
844 | +# -*- encoding: utf-8 -*- |
845 | +############################################################################## |
846 | +# |
847 | +# OpenERP, Open Source Management Solution |
848 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
849 | +# All Rights Reserved |
850 | +# |
851 | +# This program is free software: you can redistribute it and/or modify |
852 | +# it under the terms of the GNU Affero General Public License as |
853 | +# published by the Free Software Foundation, either version 3 of the |
854 | +# License, or (at your option) any later version. |
855 | +# |
856 | +# This program is distributed in the hope that it will be useful, |
857 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
858 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
859 | +# GNU Affero General Public License for more details. |
860 | +# |
861 | +# You should have received a copy of the GNU Affero General Public License |
862 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
863 | +# |
864 | +############################################################################## |
865 | + |
866 | +import attach_mail_manually |
867 | |
868 | === added file 'fetchmail_attach_from_folder/wizard/attach_mail_manually.py' |
869 | --- fetchmail_attach_from_folder/wizard/attach_mail_manually.py 1970-01-01 00:00:00 +0000 |
870 | +++ fetchmail_attach_from_folder/wizard/attach_mail_manually.py 2014-02-03 09:33:52 +0000 |
871 | @@ -0,0 +1,114 @@ |
872 | +# -*- encoding: utf-8 -*- |
873 | +############################################################################## |
874 | +# |
875 | +# OpenERP, Open Source Management Solution |
876 | +# This module copyright (C) 2013 Therp BV (<http://therp.nl>) |
877 | +# All Rights Reserved |
878 | +# |
879 | +# This program is free software: you can redistribute it and/or modify |
880 | +# it under the terms of the GNU Affero General Public License as |
881 | +# published by the Free Software Foundation, either version 3 of the |
882 | +# License, or (at your option) any later version. |
883 | +# |
884 | +# This program is distributed in the hope that it will be useful, |
885 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
886 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
887 | +# GNU Affero General Public License for more details. |
888 | +# |
889 | +# You should have received a copy of the GNU Affero General Public License |
890 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
891 | +# |
892 | +############################################################################## |
893 | + |
894 | +from openerp.osv import fields |
895 | +from openerp.osv.orm import TransientModel |
896 | + |
897 | + |
898 | +class attach_mail_manually(TransientModel): |
899 | + _name = 'fetchmail.attach.mail.manually' |
900 | + |
901 | + _columns = { |
902 | + 'folder_id': fields.many2one('fetchmail.server.folder', 'Folder', |
903 | + readonly=True), |
904 | + 'mail_ids': fields.one2many( |
905 | + 'fetchmail.attach.mail.manually.mail', 'wizard_id', 'Emails'), |
906 | + } |
907 | + |
908 | + def default_get(self, cr, uid, fields_list, context=None): |
909 | + if context is None: |
910 | + context = {} |
911 | + |
912 | + defaults = super(attach_mail_manually, self).default_get(cr, uid, |
913 | + fields_list, context) |
914 | + |
915 | + for folder in self.pool.get('fetchmail.server.folder').browse(cr, uid, |
916 | + [context.get('default_folder_id')], context): |
917 | + defaults['mail_ids']=[] |
918 | + connection = folder.server_id.connect() |
919 | + connection.select(folder.path) |
920 | + result, msgids = connection.search(None, |
921 | + 'FLAGGED' if folder.flag_nonmatching else 'UNDELETED') |
922 | + if result != 'OK': |
923 | + logger.error('Could not search mailbox %s on %s' % ( |
924 | + folder.path, this.server)) |
925 | + continue |
926 | + attach_mail_manually_mail._columns['object_id'].selection=[ |
927 | + (folder.model_id.model, folder.model_id.name)] |
928 | + for msgid in msgids[0].split(): |
929 | + result, msgdata = connection.fetch(msgid, '(RFC822)') |
930 | + if result != 'OK': |
931 | + logger.error('Could not fetch %s in %s on %s' % ( |
932 | + msgid, folder.path, this.server)) |
933 | + continue |
934 | + mail_message = self.pool.get('mail.thread').message_parse( |
935 | + cr, uid, msgdata[0][1], |
936 | + save_original=folder.server_id.original, |
937 | + context=context) |
938 | + defaults['mail_ids'].append((0, 0, { |
939 | + 'msgid': msgid, |
940 | + 'subject': mail_message.get('subject', ''), |
941 | + 'date': mail_message.get('date', ''), |
942 | + 'object_id': folder.model_id.model+',False' |
943 | + })) |
944 | + connection.close() |
945 | + |
946 | + return defaults |
947 | + |
948 | + def attach_mails(self, cr, uid, ids, context=None): |
949 | + for this in self.browse(cr, uid, ids, context): |
950 | + for mail in this.mail_ids: |
951 | + connection = this.folder_id.server_id.connect() |
952 | + connection.select(this.folder_id.path) |
953 | + result, msgdata = connection.fetch(mail.msgid, '(RFC822)') |
954 | + if result != 'OK': |
955 | + logger.error('Could not fetch %s in %s on %s' % ( |
956 | + msgid, folder.path, this.server)) |
957 | + continue |
958 | + |
959 | + mail_message = self.pool.get('mail.thread').message_parse( |
960 | + cr, uid, msgdata[0][1], |
961 | + save_original=this.folder_id.server_id.original, |
962 | + context=context) |
963 | + |
964 | + this.folder_id.server_id.attach_mail(connection, |
965 | + mail.object_id.id, this.folder_id, mail_message, |
966 | + mail.msgid) |
967 | + connection.close() |
968 | + return {'type': 'ir.actions.act_window_close'} |
969 | + |
970 | +class attach_mail_manually_mail(TransientModel): |
971 | + _name = 'fetchmail.attach.mail.manually.mail' |
972 | + |
973 | + _columns = { |
974 | + 'wizard_id': fields.many2one('fetchmail.attach.mail.manually', |
975 | + readonly=True), |
976 | + 'msgid': fields.char('Message id', size=16, readonly=True), |
977 | + 'subject': fields.char('Subject', size=128, readonly=True), |
978 | + 'date': fields.datetime('Date', readonly=True), |
979 | + 'object_id': fields.reference('Object', |
980 | + selection=lambda self, cr, uid, context: |
981 | + [(m.model, m.name) for m in |
982 | + self.pool.get('ir.model').browse(cr, uid, |
983 | + self.pool.get('ir.model').search(cr, uid, []), |
984 | + context)], size=128), |
985 | + } |
986 | |
987 | === added file 'fetchmail_attach_from_folder/wizard/attach_mail_manually.xml' |
988 | --- fetchmail_attach_from_folder/wizard/attach_mail_manually.xml 1970-01-01 00:00:00 +0000 |
989 | +++ fetchmail_attach_from_folder/wizard/attach_mail_manually.xml 2014-02-03 09:33:52 +0000 |
990 | @@ -0,0 +1,29 @@ |
991 | +<?xml version="1.0" encoding="utf-8"?> |
992 | +<openerp> |
993 | + <data> |
994 | + <record model="ir.ui.view" id="view_attach_mail_manually"> |
995 | + <field name="name">fetchmail.attach.mail.manually</field> |
996 | + <field name="model">fetchmail.attach.mail.manually</field> |
997 | + <field name="arch" type="xml"> |
998 | + <form col="4" version="7.0" string="Attach mail manually"> |
999 | + <sheet> |
1000 | + <group> |
1001 | + <field name="folder_id" /> |
1002 | + <field name="mail_ids" nolabel="1" colspan="4"> |
1003 | + <tree editable="top" create="0"> |
1004 | + <field name="subject" /> |
1005 | + <field name="date" /> |
1006 | + <field name="object_id" /> |
1007 | + </tree> |
1008 | + </field> |
1009 | + </group> |
1010 | + </sheet> |
1011 | + <footer> |
1012 | + <button string="Save" type="object" name="attach_mails" icon="gtk-ok" /> |
1013 | + <button special="cancel" string="Cancel" icon="gtk-cancel" /> |
1014 | + </footer> |
1015 | + </form> |
1016 | + </field> |
1017 | + </record> |
1018 | + </data> |
1019 | +</openerp> |
Thanks! I took a diff from the version in lp:server-env-tools/6.1 and the diff is short and clean like you would expect. Only nit I could come up with is ll.788,995: type specification in views is deprecated in 7.0.