diff --git a/.travis.yml b/.travis.yml index 32f023adc..04e5345e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,25 @@ language: python + python: - "2.7" +env: + - VERSION="7.0" ODOO_REPO="odoo/odoo" + - VERSION="7.0" ODOO_REPO="OCA/OCB" + virtualenv: system_site_packages: true install: - - git clone https://github.com/yvaucher/maintainer-quality-tools.git $HOME/maintainer-quality-tools - - export PATH=$HOME/maintainer-quality-tools/travis:$PATH - - travis_install_nightly 7.0 - - pip install coveralls flake8 - - pip install python-ldap - - printf '[options]\n\nrunning_env = dev' > /tmp/odoo.cfg + - git clone https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools + - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} + - travis_install_nightly ${VERSION} + - sudo pip install python-ldap + - printf '[options]\n\nrunning_env = dev' > ${HOME}/.openerp_serverrc script: - - travis_run_flake8 - - travis_run_tests 7.0 /tmp/odoo.cfg + - travis_run_flake8 + - travis_run_tests ${VERSION} after_success: coveralls diff --git a/base_external_dbsource/base_external_dbsource.py b/base_external_dbsource/base_external_dbsource.py index 7353a1d9c..9beb69e9e 100644 --- a/base_external_dbsource/base_external_dbsource.py +++ b/base_external_dbsource/base_external_dbsource.py @@ -35,14 +35,14 @@ try: import pymssql CONNECTORS.append(('mssql', 'Microsoft SQL Server')) assert pymssql - except ImportError, AssertionError: + except (ImportError, AssertionError): _logger.info('MS SQL Server not available. Please install "pymssql"\ python package.') try: import MySQLdb CONNECTORS.append(('mysql', 'MySQL')) assert MySQLdb - except ImportError, AssertionError: + except (ImportError, AssertionError): _logger.info('MySQL not available. Please install "mysqldb"\ python package.') except: @@ -159,7 +159,7 @@ Sample connection strings: conn = False try: conn = self.conn_open(cr, uid, obj.id) - except Exception, e: + except Exception as e: raise orm.except_orm(_("Connection test failed!"), _("Here is what we got instead:\n %s") % tools.ustr(e)) diff --git a/base_external_dbsource/test/dbsource_connect.yml b/base_external_dbsource/test/dbsource_connect.yml index 1eabcf2b2..f1105697d 100644 --- a/base_external_dbsource/test/dbsource_connect.yml +++ b/base_external_dbsource/test/dbsource_connect.yml @@ -2,4 +2,8 @@ Connect to local Postgres. - !python {model: base.external.dbsource}: | - self.connection_test(cr, uid, [ref("demo_postgresql")] + from openerp.osv.orm import except_orm + try: + self.connection_test(cr, uid, [ref("demo_postgre")]) + except except_orm as e: + assert e.value == u'Everything seems properly set up!' diff --git a/cron_run_manually/model/ir_cron.py b/cron_run_manually/model/ir_cron.py index 22c7f0720..3d7a30fa3 100644 --- a/cron_run_manually/model/ir_cron.py +++ b/cron_run_manually/model/ir_cron.py @@ -70,7 +70,7 @@ class irCron(orm.Model): args = safe_eval('tuple(%s)' % (job['args'] or '')) method(cr, job['user_id'], *args) - except psycopg2.OperationalError, e: + except psycopg2.OperationalError as e: # User friendly error if the lock could not be claimed if e.pgcode == '55P03': raise orm.except_orm( diff --git a/disable_openerp_online/data/ir_ui_menu.xml b/disable_openerp_online/data/ir_ui_menu.xml index 72529f77a..7ee89ee48 100644 --- a/disable_openerp_online/data/ir_ui_menu.xml +++ b/disable_openerp_online/data/ir_ui_menu.xml @@ -1,7 +1,7 @@ - - + + diff --git a/fetchmail_attach_from_folder/match_algorithm/base.py b/fetchmail_attach_from_folder/match_algorithm/base.py index 5116c929a..a3d9ba6b8 100644 --- a/fetchmail_attach_from_folder/match_algorithm/base.py +++ b/fetchmail_attach_from_folder/match_algorithm/base.py @@ -20,6 +20,7 @@ # ############################################################################## + class base(object): name = None '''Name shown to the user''' @@ -30,7 +31,6 @@ class base(object): readonly_fields = [] '''Fields on fetchmail_server folder that are readonly for this algorithm''' - def search_matches(self, cr, uid, conf, mail_message, mail_message_org): '''Returns ids found for model with mail_message''' return [] @@ -40,4 +40,4 @@ class base(object): mail_message, mail_message_org, msgid, context=None): '''Do whatever it takes to handle a match''' return folder.server_id.attach_mail(connection, object_id, folder, - mail_message, msgid) + mail_message, msgid) diff --git a/fetchmail_attach_from_folder/match_algorithm/email_domain.py b/fetchmail_attach_from_folder/match_algorithm/email_domain.py index 66ab66286..da2ec8ac8 100644 --- a/fetchmail_attach_from_folder/match_algorithm/email_domain.py +++ b/fetchmail_attach_from_folder/match_algorithm/email_domain.py @@ -22,6 +22,7 @@ from email_exact import email_exact + class email_domain(email_exact): '''Search objects by domain name of email address. Beware of match_first here, this is most likely to get it wrong (gmail)''' @@ -29,16 +30,16 @@ class email_domain(email_exact): def search_matches(self, cr, uid, conf, mail_message, mail_message_org): ids = super(email_domain, self).search_matches( - cr, uid, conf, mail_message, mail_message_org) + cr, uid, conf, mail_message, mail_message_org) if not ids: domains = [] for addr in self._get_mailaddresses(conf, mail_message): domains.append(addr.split('@')[-1]) ids = conf.pool.get(conf.model_id.model).search( - cr, uid, - self._get_mailaddress_search_domain( - conf, mail_message, - operator='like', - values=['%@'+domain for domain in set(domains)]), - order=conf.model_order) + cr, uid, + self._get_mailaddress_search_domain( + conf, mail_message, + operator='like', + values=['%@'+domain for domain in set(domains)]), + order=conf.model_order) return ids diff --git a/fetchmail_attach_from_folder/match_algorithm/email_exact.py b/fetchmail_attach_from_folder/match_algorithm/email_exact.py index 728c04461..b5686a183 100644 --- a/fetchmail_attach_from_folder/match_algorithm/email_exact.py +++ b/fetchmail_attach_from_folder/match_algorithm/email_exact.py @@ -24,6 +24,7 @@ from base import base from openerp.tools.safe_eval import safe_eval from openerp.tools.mail import email_split + class email_exact(base): '''Search for exactly the mailadress as noted in the email''' @@ -36,17 +37,17 @@ class email_exact(base): for field in fields: if field in mail_message: mailaddresses += email_split(mail_message[field]) - return [ addr.lower() for addr in mailaddresses ] + return [addr.lower() for addr in mailaddresses] def _get_mailaddress_search_domain( self, conf, mail_message, operator='=', values=None): mailaddresses = values or self._get_mailaddresses( - conf, mail_message) + conf, mail_message) if not mailaddresses: return [(0, '=', 1)] search_domain = ((['|'] * (len(mailaddresses) - 1)) + [ - (conf.model_field, operator, addr) for addr in mailaddresses] + - safe_eval(conf.domain or '[]')) + (conf.model_field, operator, addr) for addr in mailaddresses] + + safe_eval(conf.domain or '[]')) return search_domain def search_matches(self, cr, uid, conf, mail_message, mail_message_org): diff --git a/fetchmail_attach_from_folder/match_algorithm/openerp_standard.py b/fetchmail_attach_from_folder/match_algorithm/openerp_standard.py index 24a233d0d..2fee96c34 100644 --- a/fetchmail_attach_from_folder/match_algorithm/openerp_standard.py +++ b/fetchmail_attach_from_folder/match_algorithm/openerp_standard.py @@ -21,15 +21,21 @@ ############################################################################## from base import base -from openerp.tools.safe_eval import safe_eval + class openerp_standard(base): '''No search at all. Use OpenERP's standard mechanism to attach mails to mail.thread objects. Note that this algorithm always matches.''' name = 'OpenERP standard' - readonly_fields = ['model_field', 'mail_field', 'match_first', 'domain', - 'model_order', 'flag_nonmatching'] + readonly_fields = [ + 'model_field', + 'mail_field', + 'match_first', + 'domain', + 'model_order', + 'flag_nonmatching', + ] def search_matches(self, cr, uid, conf, mail_message, mail_message_org): '''Always match. Duplicates will be fished out by message_id''' @@ -39,11 +45,12 @@ class openerp_standard(base): self, cr, uid, connection, object_id, folder, mail_message, mail_message_org, msgid, context): result = folder.pool.get('mail.thread').message_process( - cr, uid, - folder.model_id.model, mail_message_org, - save_original=folder.server_id.original, - strip_attachments=(not folder.server_id.attach), - context=context) + cr, uid, + folder.model_id.model, mail_message_org, + save_original=folder.server_id.original, + strip_attachments=(not folder.server_id.attach), + context=context + ) if folder.delete_matching: connection.store(msgid, '+FLAGS', '\\DELETED') diff --git a/fetchmail_attach_from_folder/model/fetchmail_server.py b/fetchmail_attach_from_folder/model/fetchmail_server.py index 814da703c..c1673c382 100644 --- a/fetchmail_attach_from_folder/model/fetchmail_server.py +++ b/fetchmail_attach_from_folder/model/fetchmail_server.py @@ -23,12 +23,11 @@ import base64 import simplejson from lxml import etree -from openerp.osv.orm import Model, except_orm, browse_null +from openerp.osv.orm import Model, except_orm from openerp.tools.translate import _ from openerp.osv import fields from openerp.addons.fetchmail.fetchmail import _logger as logger from openerp.tools.misc import UnquoteEvalContext -from openerp.tools.safe_eval import safe_eval class fetchmail_server(Model): @@ -36,7 +35,7 @@ class fetchmail_server(Model): _columns = { 'folder_ids': fields.one2many( - 'fetchmail.server.folder', 'server_id', 'Folders'), + 'fetchmail.server.folder', 'server_id', 'Folders'), } _defaults = { @@ -95,20 +94,19 @@ class fetchmail_server(Model): if connection.select(folder.path)[0] != 'OK': logger.error( - 'Could not open mailbox %s on %s' % ( - folder.path, this.server)) + 'Could not open mailbox %s on %s' % (folder.path, this.server)) connection.select() continue result, msgids = this.get_msgids(connection) if result != 'OK': logger.error( 'Could not search mailbox %s on %s' % ( - folder.path, this.server)) + folder.path, this.server)) continue for msgid in msgids[0].split(): matched_object_ids += this.apply_matching( - connection, folder, msgid, match_algorithm) + connection, folder, msgid, match_algorithm) logger.info('finished checking for emails in %s server %s', folder.path, this.name) @@ -130,16 +128,16 @@ class fetchmail_server(Model): if result != 'OK': logger.error( - 'Could not fetch %s in %s on %s' % ( - msgid, folder.path, this.server)) + 'Could not fetch %s in %s on %s' % (msgid, folder.path, this.server)) continue mail_message = self.pool.get('mail.thread').message_parse( - cr, uid, msgdata[0][1], save_original=this.original, - context=context) + cr, uid, msgdata[0][1], save_original=this.original, + context=context) - if self.pool.get('mail.message').search(cr, uid, [ - ('message_id', '=', mail_message['message_id'])]): + if self.pool.get('mail.message').search( + cr, uid, [ + ('message_id', '=', mail_message['message_id'])]): continue found_ids = match_algorithm.search_matches( @@ -156,7 +154,7 @@ class fetchmail_server(Model): msgdata[0][1], msgid, context) cr.execute('release savepoint apply_matching') matched_object_ids += found_ids[:1] - except Exception, e: + except Exception: cr.execute('rollback to savepoint apply_matching') logger.exception( "Failed to fetch mail %s from %s", @@ -183,40 +181,40 @@ class fetchmail_server(Model): cr, uid, object_id, context ).partner_id.id - attachments=[] + attachments = [] if this.attach and mail_message.get('attachments'): for attachment in mail_message['attachments']: fname, fcontent = attachment if isinstance(fcontent, unicode): fcontent = fcontent.encode('utf-8') data_attach = { - 'name': fname, - 'datas': base64.b64encode(str(fcontent)), - 'datas_fname': fname, - 'description': _('Mail attachment'), - 'res_model': folder.model_id.model, - 'res_id': object_id, - } + 'name': fname, + 'datas': base64.b64encode(str(fcontent)), + 'datas_fname': fname, + 'description': _('Mail attachment'), + 'res_model': folder.model_id.model, + 'res_id': object_id, + } attachments.append( self.pool.get('ir.attachment').create( cr, uid, data_attach, context=context)) mail_message_ids.append( - self.pool.get('mail.message').create( - cr, uid, - { - 'author_id': partner_id, - 'model': folder.model_id.model, - 'res_id': object_id, - 'type': 'email', - 'body': mail_message.get('body'), - 'subject': mail_message.get('subject'), - 'email_from': mail_message.get('from'), - 'date': mail_message.get('date'), - 'message_id': mail_message.get('message_id'), - 'attachment_ids': [(6, 0, attachments)], - }, - context)) + self.pool.get('mail.message').create( + cr, uid, + { + 'author_id': partner_id, + 'model': folder.model_id.model, + 'res_id': object_id, + 'type': 'email', + 'body': mail_message.get('body'), + 'subject': mail_message.get('subject'), + 'email_from': mail_message.get('from'), + 'date': mail_message.get('date'), + 'message_id': mail_message.get('message_id'), + 'attachment_ids': [(6, 0, attachments)], + }, + context)) if folder.delete_matching: connection.store(msgid, '+FLAGS', '\\DELETED') diff --git a/fetchmail_attach_from_folder/model/fetchmail_server_folder.py b/fetchmail_attach_from_folder/model/fetchmail_server_folder.py index ea0c07a7b..8021332e2 100644 --- a/fetchmail_attach_from_folder/model/fetchmail_server_folder.py +++ b/fetchmail_attach_from_folder/model/fetchmail_server_folder.py @@ -47,55 +47,66 @@ class fetchmail_server_folder(Model): _columns = { 'sequence': fields.integer('Sequence'), 'path': fields.char( - 'Path', size=256, help='The path to your mail ' - "folder. Typically would be something like 'INBOX.myfolder'", - required=True), + 'Path', size=256, help='The path to your mail ' + "folder. Typically would be something like 'INBOX.myfolder'", + required=True + ), 'model_id': fields.many2one( - 'ir.model', 'Model', required=True, - help='The model to attach emails to'), + 'ir.model', 'Model', required=True, + help='The model to attach emails to' + ), 'model_field': fields.char( - 'Field (model)', size=128, - help='The field in your model that contains the field to match ' - 'against.\n' - 'Examples:\n' - "'email' if your model is res.partner, or " - "'partner_id.email' if you're matching sale orders"), + 'Field (model)', size=128, + help='The field in your model that contains the field to match ' + 'against.\n' + 'Examples:\n' + "'email' if your model is res.partner, or " + "'partner_id.email' if you're matching sale orders" + ), 'model_order': fields.char( - 'Order (model)', size=128, - help='Fields to order by, this mostly useful in conjunction ' - "with 'Use 1st match'"), + 'Order (model)', size=128, + help='Fields to order by, this mostly useful in conjunction ' + "with 'Use 1st match'" + ), 'match_algorithm': fields.selection( - _get_match_algorithms_sel, - 'Match algorithm', required=True, translate=True, - help='The algorithm used to determine which object an email ' - 'matches.'), + _get_match_algorithms_sel, + 'Match algorithm', required=True, translate=True, + help='The algorithm used to determine which object an email ' + 'matches.' + ), 'mail_field': fields.char( - 'Field (email)', size=128, - help='The field in the email used for matching. Typically ' - "this is 'to' or 'from'"), + 'Field (email)', size=128, + help='The field in the email used for matching. Typically ' + "this is 'to' or 'from'" + ), 'server_id': fields.many2one('fetchmail.server', 'Server'), 'delete_matching': fields.boolean( - 'Delete matches', - help='Delete matched emails from server'), + 'Delete matches', + help='Delete matched emails from server' + ), 'flag_nonmatching': fields.boolean( - 'Flag nonmatching', - help="Flag emails in the server that don't match any object " - 'in OpenERP'), + 'Flag nonmatching', + help="Flag emails in the server that don't match any object " + 'in OpenERP' + ), 'match_first': fields.boolean( - 'Use 1st match', - help='If there are multiple matches, use the first one. If ' - 'not checked, multiple matches count as no match at all'), + 'Use 1st match', + help='If there are multiple matches, use the first one. If ' + 'not checked, multiple matches count as no match at all' + ), 'domain': fields.char( - 'Domain', size=128, help='Fill in a search ' - 'filter to narrow down objects to match'), + 'Domain', size=128, help='Fill in a search ' + 'filter to narrow down objects to match' + ), 'msg_state': fields.selection( - [ - ('sent', 'Sent'), - ('received', 'Received'), - ], - 'Message state', - help='The state messages fetched from this folder should be ' - 'assigned in OpenERP'), + [ + ('sent', 'Sent'), + ('received', 'Received'), + ], + 'Message state', + help='The state messages fetched from this folder should be ' + 'assigned in OpenERP' + ), } _defaults = { diff --git a/fetchmail_attach_from_folder/wizard/attach_mail_manually.py b/fetchmail_attach_from_folder/wizard/attach_mail_manually.py index d1a16fa1f..18b851be2 100644 --- a/fetchmail_attach_from_folder/wizard/attach_mail_manually.py +++ b/fetchmail_attach_from_folder/wizard/attach_mail_manually.py @@ -22,48 +22,54 @@ from openerp.osv import fields from openerp.osv.orm import TransientModel +import logging +logger = logging.getLogger(__name__) class attach_mail_manually(TransientModel): _name = 'fetchmail.attach.mail.manually' _columns = { - 'folder_id': fields.many2one('fetchmail.server.folder', 'Folder', - readonly=True), - 'mail_ids': fields.one2many( - 'fetchmail.attach.mail.manually.mail', 'wizard_id', 'Emails'), - } + 'folder_id': fields.many2one('fetchmail.server.folder', 'Folder', + readonly=True), + 'mail_ids': fields.one2many( + 'fetchmail.attach.mail.manually.mail', 'wizard_id', 'Emails'), + } def default_get(self, cr, uid, fields_list, context=None): if context is None: context = {} - defaults = super(attach_mail_manually, self).default_get(cr, uid, - fields_list, context) + defaults = super(attach_mail_manually, self).default_get( + cr, uid, fields_list, context + ) - for folder in self.pool.get('fetchmail.server.folder').browse(cr, uid, + for folder in self.pool.get('fetchmail.server.folder').browse( + cr, uid, [context.get('default_folder_id')], context): - defaults['mail_ids']=[] + defaults['mail_ids'] = [] connection = folder.server_id.connect() connection.select(folder.path) - result, msgids = connection.search(None, - 'FLAGGED' if folder.flag_nonmatching else 'UNDELETED') + result, msgids = connection.search( + None, + 'FLAGGED' if folder.flag_nonmatching else 'UNDELETED') if result != 'OK': logger.error('Could not search mailbox %s on %s' % ( - folder.path, this.server)) + folder.path, folder.server_id.name)) continue - attach_mail_manually_mail._columns['object_id'].selection=[ - (folder.model_id.model, folder.model_id.name)] + attach_mail_manually_mail._columns['object_id'].selection = [ + (folder.model_id.model, folder.model_id.name)] for msgid in msgids[0].split(): result, msgdata = connection.fetch(msgid, '(RFC822)') if result != 'OK': logger.error('Could not fetch %s in %s on %s' % ( - msgid, folder.path, this.server)) + msgid, folder.path, folder.server_id.name)) continue mail_message = self.pool.get('mail.thread').message_parse( - cr, uid, msgdata[0][1], - save_original=folder.server_id.original, - context=context) + cr, uid, msgdata[0][1], + save_original=folder.server_id.original, + context=context + ) defaults['mail_ids'].append((0, 0, { 'msgid': msgid, 'subject': mail_message.get('subject', ''), @@ -79,36 +85,45 @@ class attach_mail_manually(TransientModel): for mail in this.mail_ids: connection = this.folder_id.server_id.connect() connection.select(this.folder_id.path) - result, msgdata = connection.fetch(mail.msgid, '(RFC822)') - if result != 'OK': - logger.error('Could not fetch %s in %s on %s' % ( - msgid, folder.path, this.server)) - continue - + result, msgdata = connection.fetch(mail.msgid, '(RFC822)') + if result != 'OK': + logger.error('Could not fetch %s in %s on %s' % ( + mail.msgid, this.folder_id.path, this.server)) + continue + mail_message = self.pool.get('mail.thread').message_parse( cr, uid, msgdata[0][1], save_original=this.folder_id.server_id.original, context=context) - this.folder_id.server_id.attach_mail(connection, - mail.object_id.id, this.folder_id, mail_message, - mail.msgid) + this.folder_id.server_id.attach_mail( + connection, + mail.object_id.id, this.folder_id, mail_message, + mail.msgid + ) connection.close() return {'type': 'ir.actions.act_window_close'} + class attach_mail_manually_mail(TransientModel): _name = 'fetchmail.attach.mail.manually.mail' _columns = { - 'wizard_id': fields.many2one('fetchmail.attach.mail.manually', - readonly=True), - 'msgid': fields.char('Message id', size=16, readonly=True), - 'subject': fields.char('Subject', size=128, readonly=True), - 'date': fields.datetime('Date', readonly=True), - 'object_id': fields.reference('Object', - selection=lambda self, cr, uid, context: - [(m.model, m.name) for m in - self.pool.get('ir.model').browse(cr, uid, - self.pool.get('ir.model').search(cr, uid, []), - context)], size=128), - } + 'wizard_id': fields.many2one('fetchmail.attach.mail.manually', + readonly=True), + 'msgid': fields.char('Message id', size=16, readonly=True), + 'subject': fields.char('Subject', size=128, readonly=True), + 'date': fields.datetime('Date', readonly=True), + 'object_id': fields.reference( + 'Object', + selection=lambda self, cr, uid, context: [ + (m.model, m.name) + for m in self.pool.get('ir.model').browse( + cr, uid, + self.pool.get('ir.model').search(cr, uid, []), + context + ) + ], + size=128, + ), + } diff --git a/server_environment/serv_config.py b/server_environment/serv_config.py index 033cc91fe..ccac4f007 100644 --- a/server_environment/serv_config.py +++ b/server_environment/serv_config.py @@ -93,7 +93,7 @@ def _load_config(): config_p.optionxform = str try: config_p.read(conf_files) - except Exception, e: + except Exception as e: raise Exception('Cannot read config files "%s": %s' % (conf_files, e)) return config_p diff --git a/server_environment/system_info.py b/server_environment/system_info.py index 5c5875eb0..e6d522d9f 100644 --- a/server_environment/system_info.py +++ b/server_environment/system_info.py @@ -38,7 +38,7 @@ def get_server_environment(): # inspired by server/bin/service/web_services.py try: rev_id = _get_output('bzr revision-info') - except Exception, e: + except Exception as e: rev_id = 'Exception: %s' % (e,) os_lang = '.'.join([x for x in locale.getdefaultlocale() if x])