1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
22 from osv import fields,osv
23 from tools.translate import _
27 import gdata.contacts.service
29 import gdata.contacts.client
31 raise osv.except_osv(_('Google Contacts Import Error!'), _('Please install gdata-python-client from http://code.google.com/p/gdata-python-client/downloads/list'))
33 class google_base_import(osv.osv_memory):
34 _inherit = 'synchronize.base.contact.wizard.import'
36 def _get_tools_name(self, cr, user, context):
38 @return the list of value of the selection field
39 should be overwritten by subclasses
41 names = super(google_base_import, self)._get_tools_name(cr, user, context=context)
42 names.append(('gmail','Gmail address book'))
47 'tools': fields.selection(_get_tools_name, 'App to synchronize with'),
51 def _get_actions_dic(self, cr, uid, context=None):
53 this method should be overwritten in specialize module
54 @return the dictonnaries of action
56 actions = super(google_base_import, self)._get_actions_dic(cr, uid, context=context)
58 data_obj = self.pool.get('ir.model.data')
59 data_id = data_obj._get_id(cr, uid, 'google_base_account', 'view_google_login_form')
62 view_id = data_obj.browse(cr, uid, data_id, context=context).res_id
65 'name': _('Import Contact'),
67 'view_mode': 'form,tree',
68 'res_model': 'google.login.contact',
71 'views': [(view_id, 'form')],
72 'type': 'ir.actions.act_window',
75 actions['gmail'] = value
80 class google_contact_import(osv.osv_memory):
81 _inherit = 'google.login'
82 _name = 'google.login.contact'
84 def _get_next_action(self, cr, uid, context=None):
85 data_obj = self.pool.get('ir.model.data')
86 data_id = data_obj._get_id(cr, uid, 'sync_google_contact', 'view_synchronize_google_contact_import_form')
89 view_id = data_obj.browse(cr, uid, data_id, context=context).res_id
91 'name': _('Import Contact'),
93 'view_mode': 'form,tree',
94 'res_model': 'synchronize.google.contact.import',
97 'views': [(view_id, 'form')],
98 'type': 'ir.actions.act_window',
103 google_contact_import()
105 class synchronize_google_contact(osv.osv_memory):
106 _name = 'synchronize.google.contact.import'
108 def _get_group(self, cr, uid, context=None):
109 user_obj = self.pool.get('res.users').browse(cr, uid, uid)
110 google=self.pool.get('google.login')
111 gd_client = google.google_login(cr,uid,user_obj.gmail_user,user_obj.gmail_password)
114 groups = gd_client.GetGroupsFeed()
115 for grp in groups.entry:
116 res.append((grp.id.text, grp.title.text))
117 res.append(('none','None'))
118 res.append(('all','All Groups'))
121 def _get_default_group(self, cr, uid, context=None):
125 'create_partner': fields.boolean('Create Partner', help="It will create Partner for given gmail user otherwise only adds contacts in Partner Addresses.") ,
126 'group_name': fields.selection(_get_group, "Group Name", size=32,help="Choose which group to import, By defult it take all "),
130 'group_name': _get_default_group,
133 def create_partner(self, cr, uid, data={}, context=None):
134 partner_obj = self.pool.get('res.partner')
135 name = data.get('name','')
136 partner_id = partner_obj.search(cr, uid, [('name','ilike',name)], context=context)
138 partner_id.append(partner_obj.create(cr, uid, {'name': name, 'address' : [(6, 0, [data['address_id']])]}, context=context))
139 return partner_id, data
141 def import_contact(self, cr, uid, ids, context=None):
142 obj=self.browse(cr, uid, ids, context=context)[0]
143 if obj.group_name == 'none':
144 return { 'type': 'ir.actions.act_window_close' }
146 user_obj = self.pool.get('res.users').browse(cr, uid, uid)
148 gmail_user = user_obj.gmail_user
149 gamil_pwd = user_obj.gmail_password
151 google = self.pool.get('google.login')
152 gd_client = google.google_login(cr,uid,user_obj.gmail_user,user_obj.gmail_password)
154 if not gmail_user or not gamil_pwd:
155 raise osv.except_osv(_('Error'), _("Please specify the user and password !"))
157 if obj.group_name not in ['all','none']:
158 query = gdata.contacts.service.ContactsQuery()
159 query.group =obj.group_name
160 contact = gd_client.GetContactsFeed(query.ToUri())
162 contact = gd_client.GetContactsFeed()
164 ids = self.create_contact( cr, uid, gd_client,contact, partner_id=obj.create_partner,context=context)
166 return {'type': 'ir.actions.act_window_close'}
169 'name': _('Partner'),
170 'domain': "[('id','in', ["+','.join(map(str,ids))+"])]",
172 'view_mode': 'tree,form',
173 'res_model': obj.create_partner and 'res.partner' or 'res.partner.address',
175 'views': [(False, 'tree'),(False, 'form')],
176 'type': 'ir.actions.act_window',
180 def create_contact(self, cr, uid, gd_client,contact, partner_id=False,context=None):
181 model_obj = self.pool.get('ir.model.data')
182 addresss_obj = self.pool.get('res.partner.address')
187 for entry in contact.entry:
190 'name': 'google_contacts_information_%s' %(entry.id.text),
191 'model': 'res.partner.address',
192 'module': 'sync_google_contact',
194 name = tools.ustr(entry.title.text)
196 name = entry.email[0].address
198 google_id = entry.id.text
199 emails = ','.join(email.address for email in entry.email)
200 if name and name != 'None':
204 model_data.update({'google_id': google_id})
205 if entry.phone_number:
206 for phone in entry.phone_number:
207 if phone.rel == gdata.contacts.REL_WORK:
208 data['phone'] = phone.text
209 if phone.rel == gdata.contacts.PHONE_MOBILE:
210 data['mobile'] = phone.text
211 if phone.rel == gdata.contacts.PHONE_WORK_FAX:
212 data['fax'] = phone.text
214 data_ids = model_obj.search(cr, uid, [('google_id','=',google_id)])
216 contact_ids = [model_obj.browse(cr, uid, data_ids[0], context=context).res_id]
218 data['email'] = emails
219 contact_ids = addresss_obj.search(cr, uid, [('email','ilike',emails)])
222 addresses.append(contact_ids[0])
223 self.update_contact(cr, uid, contact_ids, data, context=context)
224 data_ids = model_obj.search(cr, uid, [('res_id','=',contact_ids[0]), ('google_id','=','')])
225 model_data.update({'google_id': google_id})
226 model_obj.write(cr, uid, data_ids, model_data, context=context)
228 #create or link to an existing partner only if it's a new contact
229 res_id = addresss_obj.create(cr, uid, data, context=context)
230 data['address_id'] = res_id
232 partner_id, data = self.create_partner(cr, uid, data, context=context)
233 partner_ids.append(partner_id[0])
234 addresses.append(res_id)
235 model_data.update({'res_id': res_id})
236 model_obj.create(cr, uid, model_data, context=context)
238 next = contact.GetNextLink()
239 contact = next and gd_client.GetContactsFeed(next.href) or None
246 def update_contact(self, cr, uid, contact_ids, data,context=None):
247 addresss_obj = self.pool.get('res.partner.address')
251 addr = addresss_obj.browse(cr,uid,contact_ids)[0]
252 name = str((addr.name or addr.partner_id and addr.partner_id.name or '').encode('utf-8'))
253 addres=addr.partner_id
259 res['name']=data.get('name','')
261 res['email']=data.get('email','')
263 res['mobile']=data.get('mobile','')
265 res['phone']=data.get('phone','')
267 res['fax']=data.get('fax','')
268 if data.get('partner_id') and not addres :
269 res['partner_id'] = data.get('partner_id')
270 addresss_obj.write(cr,uid,contact_ids,res,context=context)
273 synchronize_google_contact()
275 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: