diff options
Diffstat (limited to 'addons/import_google/wizard')
| -rw-r--r-- | addons/import_google/wizard/__init__.py | 24 | ||||
| -rw-r--r-- | addons/import_google/wizard/google_import_message.py | 42 | ||||
| -rw-r--r-- | addons/import_google/wizard/google_import_message_view.xml | 25 | ||||
| -rw-r--r-- | addons/import_google/wizard/import_google.py | 355 | ||||
| -rw-r--r-- | addons/import_google/wizard/import_google_data.py | 182 | ||||
| -rw-r--r-- | addons/import_google/wizard/import_google_data_view.xml | 91 |
6 files changed, 719 insertions, 0 deletions
diff --git a/addons/import_google/wizard/__init__.py b/addons/import_google/wizard/__init__.py new file mode 100644 index 00000000000..41c118a0ef3 --- /dev/null +++ b/addons/import_google/wizard/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## +import import_google +import import_google_data +import google_import_message +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/import_google/wizard/google_import_message.py b/addons/import_google/wizard/google_import_message.py new file mode 100644 index 00000000000..5e2b2b6f4b1 --- /dev/null +++ b/addons/import_google/wizard/google_import_message.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +from osv import osv +from osv import fields + + +class google_import_message(osv.osv): + """Import Message""" + + _name = "google.import.message" + _description = "Import Message" + _columns = { + 'name': fields.text('Message', readonly=True), + } + + def default_get(self, cr, uid, fields, context=None): + if context == None: + context = {} + res = super(google_import_message, self).default_get(cr, uid, fields, context=context) + res.update({'name': context.get('message')}) + return res + +google_import_message() diff --git a/addons/import_google/wizard/google_import_message_view.xml b/addons/import_google/wizard/google_import_message_view.xml new file mode 100644 index 00000000000..0ea8b15f286 --- /dev/null +++ b/addons/import_google/wizard/google_import_message_view.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<openerp> + <data> + <!-- Import Message Form View --> + <record model="ir.ui.view" id="view_google_import_message_form"> + <field name="name">google.import.message.form</field> + <field name="model">google.import.message</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Import Google Data"> + <group colspan="4" col="4" width="300"> + <field name='name' nolabel='1'/> + </group> + <separator string="" colspan="4"/> + <group colspan="4"> + <group colspan="2"/> + <group colspan="2"> + <button icon="gtk-ok" special="cancel" string="_Ok"/> + </group> + </group> + </form> + </field> + </record> + </data> +</openerp> diff --git a/addons/import_google/wizard/import_google.py b/addons/import_google/wizard/import_google.py new file mode 100644 index 00000000000..87155c806c6 --- /dev/null +++ b/addons/import_google/wizard/import_google.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +import re +import urllib +import dateutil +import pytz +from dateutil import * +from pytz import timezone +from datetime import datetime +import time +from osv import * +try: + import gdata + import gdata.contacts.service + import gdata.calendar.service + import gdata.contacts + import gdata.calendar +except ImportError: + raise osv.except_osv(_('Google Contacts Import Error!'), _('Please install gdata-python-client from http://code.google.com/p/gdata-python-client/downloads/list')) +from import_base.import_framework import * +from import_base.mapper import * + +class google_import(import_framework): + + gd_client = False + calendars = False + contact = False + DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S" + TABLE_CONTACT = 'Contact' + TABLE_ADDRESS ='Address' + TABLE_EVENT = 'Events' + + def initialize(self): + google = self.obj.pool.get('google.login') + self.external_id_field = 'Id' + self.gd_client = google.google_login(self.context.get('user'), + self.context.get('password'), + self.context.get('instance')) + + if self.context.get('instance') and self.context.get('instance') == 'contact': + self.contact = self.context.get('contact') + if self.context.get('instance') and self.context.get('instance') == 'calendar': + self.calendars = self.context.get('calendars') + + def get_mapping(self): + return { + self.TABLE_EVENT: self.get_event_mapping(), + self.TABLE_CONTACT: self.get_contact_mapping(), + self.TABLE_ADDRESS: self.get_address_mapping(), + } + + def get_data(self, table): + data_fetching_function = { + self.TABLE_CONTACT: self.get_contact, + self.TABLE_ADDRESS: self.get_contact, + self.TABLE_EVENT: self.get_events, + } + + return data_fetching_function.get(table)() + + + def _get_tinydates(self, stime, etime, au_tz): + stime = dateutil.parser.parse(stime) + etime = dateutil.parser.parse(etime) + try: + au_dt = au_tz.normalize(stime.replace(tzinfo=pytz.utc).astimezone(au_tz)) + timestring = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S') + au_dt = au_tz.normalize(etime.replace(tzinfo=pytz.utc).astimezone(au_tz)) + timestring_end = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S') + except: + timestring = datetime.datetime(*stime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S') + timestring_end = datetime.datetime(*etime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S') + return (timestring, timestring_end) + + def _get_rules(self, datas): + new_val = {} + if datas['FREQ'] == 'WEEKLY' and datas.get('BYDAY'): + for day in datas['BYDAY'].split(','): + new_val[day.lower()] = True + datas.pop('BYDAY') + + if datas.get('UNTIL'): + until = parser.parse(''.join((re.compile('\d')).findall(datas.get('UNTIL')))) + new_val['end_date'] = until.strftime('%Y-%m-%d') + new_val['end_type'] = 'end_date' + datas.pop('UNTIL') + + if datas.get('COUNT'): + new_val['count'] = datas.get('COUNT') + new_val['end_type'] = 'count' + datas.pop('COUNT') + + if datas.get('INTERVAL'): + new_val['interval'] = datas.get('INTERVAL') + else: + new_val['interval'] = 1 + + if datas.get('BYMONTHDAY'): + new_val['day'] = datas.get('BYMONTHDAY') + datas.pop('BYMONTHDAY') + new_val['select1'] = 'date' + + if datas.get('BYDAY'): + d = datas.get('BYDAY') + if '-' in d: + new_val['byday'] = d[:2] + new_val['week_list'] = d[2:4].upper() + else: + new_val['byday'] = d[:1] + new_val['week_list'] = d[1:3].upper() + new_val['select1'] = 'day' + + if datas.get('BYMONTH'): + new_val['month_list'] = datas.get('BYMONTH') + datas.pop('bymonth') + return new_val + + + def _get_repeat_status(self, str_google): + rrule = str_google[str_google.find('FREQ'):str_google.find('\nBEGIN')] + status = {} + for rule in rrule.split(';'): + status[rule.split('=')[0]] = rule.split('=')[-1:] and rule.split('=')[-1:][0] or '' + rules = self._get_rules(status) + if status.get('FREQ') == 'WEEKLY': + status.update({'rrule_type': 'weekly'}) + status.pop('FREQ') + elif status.get('FREQ') == 'DAILY': + status.update({'rrule_type': 'daily'}) + status.pop('FREQ') + elif status.get('FREQ') == 'MONTHLY': + status.update({'rrule_type': 'monthly'}) + status.pop('FREQ') + elif status.get('FREQ') == 'YEARLY': + status.update({'rrule_type': 'yearly'}) + status.pop('FREQ') + status.update(rules) + return status + + + def _get_repeat_dates(self, x): + if len(x) > 4: + if x[3].startswith('BY'): + zone_time = x[4].split('+')[-1:][0].split(':')[0][:4] + else: + zone_time = x[3].split('+')[-1:][0].split(':')[0][:4] + else: + zone_time = x[2].split('+')[-1:][0].split(':')[0][:4] + tz_format = zone_time[:2]+':'+zone_time[2:] + repeat_start = x[1].split('\n')[0].split(':')[1] + repeat_end = x[2].split('\n')[0].split(':')[1] + o = repeat_start.split('T') + repeat_start = str(o[0][:4]) + '-' + str(o[0][4:6]) + '-' + str(o[0][6:8]) + if len(o) == 2: + repeat_start += ' ' + str(o[1][:2]) + ':' + str(o[1][2:4]) + ':' + str(o[1][4:6]) + else: + repeat_start += ' ' + '00' + ':' + '00' + ':' + '00' + p = repeat_end.split('T') + repeat_end = str(p[0][:4]) + '-' + str(p[0][4:6]) + '-' + str(p[0][6:8]) + if len(p) == 2: + repeat_end += ' ' + str(p[1][:2]) + ':' + str(p[1][2:4]) + ':' + str(p[1][4:6]) + else: + repeat_end += ' ' + '00' + ':' + '00' + ':' + '00' + return (repeat_start, repeat_end, tz_format) + + def get_events(self): + if 'tz' in self.context and self.context['tz']: + time_zone = self.context['tz'] + else: + time_zone = tools.get_server_timezone() + au_tz = timezone(time_zone) + event_vals = [] + for cal in self.calendars: + events_query = gdata.calendar.service.CalendarEventQuery(user=urllib.unquote(cal.split('/')[~0])) + events_query.start_index = 1 + events_query.max_results = 1000 + event_feed = self.gd_client.GetCalendarEventFeed(events_query.ToUri()) + for feed in event_feed.entry: + event = { + 'recurrency': False, + 'end_date' : False, + 'end_type' : False, + 'byday': 0, + 'count' : 0, + 'interval': 1, + 'day': False, + 'select1': False, + 'week_list': "", + 'month_list': False, + 'rrule_type': False, + } + + timestring = timestring_end = datetime.datetime.now().strftime(self.DATETIME_FORMAT) + if feed.when: + timestring, timestring_end = self._get_tinydates(feed.when[0].start_time, feed.when[0].end_time, au_tz) + else: + x = feed.recurrence.text.split(';') + repeat_status = self._get_repeat_status(feed.recurrence.text) + repeat_start, repeat_end, zone_time = self._get_repeat_dates(x) + timestring = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_start, "%Y-%m-%d %H:%M:%S")) + timestring_end = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_end, "%Y-%m-%d %H:%M:%S")) + if repeat_status: + repeat_status.update({'recurrency': True}) + event.update(repeat_status) + + event.update({'id' : feed.id.text, + 'DateStart': timestring, + 'DateEnd': timestring_end, + 'Category':event_feed.title.text, + 'Name': feed.title.text or 'No title', + 'Description': feed.content.text, + }) + event_vals.append(event) + return event_vals + + + def get_event_category(self, val, name): + fields = ['name', 'object_id'] + nameid = 'event_category_'+name + data = [name, 'crm.meeting'] + return self.import_object(fields, data, 'crm.case.categ', "crm_case_categ", nameid, [('name', 'ilike', name)]) + + def get_rec(self, val): + if val.get("recurrency"): + return "1" + return "0" + + def get_event_mapping(self): + return { + 'model': 'crm.meeting', + 'map': { + 'id': 'id', + 'name': 'Name', + 'description': 'Description', + 'email_from': 'Email', + 'date': 'DateStart', + 'date_deadline': 'DateEnd', + 'categ_id/id': call(self.get_event_category, value('Category')), + 'recurrency': self.get_rec, + 'end_date' : 'end_date', + 'end_type' : 'end_type', + 'byday':'byday', + 'count' : 'count', + 'interval': 'interval', + 'day': 'day', + 'select1': 'date', + 'week_list': 'week_list', + 'month_list':'month_list', + 'rrule_type': 'rrule_type', + } + } + + + def get_contact(self): + table = self.context.get('table')[0] + datas = [] + if self.context.get('group_name'): + query = gdata.contacts.service.ContactsQuery() + query.group = self.context.get('group_name') + self.contact = self.gd_client.GetContactsFeed(query.ToUri()) + else: + self.contact = self.gd_client.GetContactsFeed() + while self.contact: + for entry in self.contact.entry: + data = {} + data['id'] = entry.id.text + name = tools.ustr(entry.title.text) + if name == "None": + name = entry.email[0].address + data['name'] = name + emails = ','.join(email.address for email in entry.email) + data['email'] = emails + if table == 'Contact': + data.update({'customer': str(self.context.get('customer')), + 'supplier': str(self.context.get('supplier'))}) + if entry.organization: + if entry.organization.org_name: + data.update({'company': entry.organization.org_name.text}) + if entry.organization.org_title: + data.update ({'function': entry.organization.org_title.text}) + if entry.phone_number: + for phone in entry.phone_number: + if phone.rel == gdata.contacts.REL_WORK: + data['phone'] = phone.text + if phone.rel == gdata.contacts.PHONE_MOBILE: + data['mobile'] = phone.text + if phone.rel == gdata.contacts.PHONE_WORK_FAX: + data['fax'] = phone.text + datas.append(data) + next = self.contact.GetNextLink() + self.contact = next and self.gd_client.GetContactsFeed(next.href) or None + return datas + + + + def get_contact_mapping(self): + return { + 'model': 'res.partner', + 'dependencies': [self.TABLE_ADDRESS], + 'map': { + 'id':'id', + 'name': value('company', fallback='name'), + 'customer': 'customer', + 'supplier': 'supplier', + 'address/id': ref(self.TABLE_ADDRESS, 'id'), + } + } + + def get_partner_id(self, val): + partner_id = False + company_pool = self.obj.pool.get('res.partner') + if 'company' in val: + partner_ids = company_pool.search(self.cr, self.uid, [('name', '=', val.get('company'))]) + return partner_ids and partner_ids[0] or False + contact = self.xml_id_exist(self.TABLE_CONTACT, val.get('id')) + if contact: + partner_id = self.get_mapped_id(self.TABLE_CONTACT, val.get('id')) + return partner_id + + def get_address_mapping(self): + return { + 'model': 'res.partner.address', + 'dependencies': [], + 'map': { + 'id':'id', + 'partner_id/.id': self.get_partner_id, + 'name': 'name', + 'city': 'city', + 'phone': 'phone', + 'mobile': 'mobile', + 'email': 'email', + 'fax': 'fax', + 'function': 'function' + } + + } diff --git a/addons/import_google/wizard/import_google_data.py b/addons/import_google/wizard/import_google_data.py new file mode 100644 index 00000000000..776cb578f08 --- /dev/null +++ b/addons/import_google/wizard/import_google_data.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## +import datetime + +try: + import gdata + import gdata.contacts.service + import gdata.contacts +except ImportError: + raise osv.except_osv(_('Google Contacts Import Error!'), _('Please install gdata-python-client from http://code.google.com/p/gdata-python-client/downloads/list')) +from osv import fields +from osv import osv +from tools.translate import _ +from import_google import google_import + + +class google_login_contact(osv.osv_memory): + + _inherit = 'google.login' + + def _get_next_action(self, cr, uid, context=None): + data_obj = self.pool.get('ir.model.data') + data_id = data_obj._get_id(cr, uid, 'import_google', 'view_synchronize_google_contact_import_form') + view_id = False + if context.get('contact'): + data_id = data_obj._get_id(cr, uid, 'import_google', 'view_synchronize_google_contact_import_form') + if context.get('calendar'): + data_id = data_obj._get_id(cr, uid, 'import_google', 'view_synchronize_google_calendar_import_form') + if data_id: + view_id = data_obj.browse(cr, uid, data_id, context=context).res_id + value = { + 'name': _('Import google'), + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'synchronize.google.import', + 'view_id': False, + 'context': context, + 'views': [(view_id, 'form')], + 'type': 'ir.actions.act_window', + 'target': 'new', + } + return value + +google_login_contact() + +class synchronize_google(osv.osv_memory): + _name = 'synchronize.google.import' + + def _get_group(self, cr, uid, context=None): + user_obj = self.pool.get('res.users').browse(cr, uid, uid) + google=self.pool.get('google.login') + if not user_obj.gmail_user or not user_obj.gmail_password: + raise osv.except_osv(_('Warning !'), _("No Google Username or password Defined for user.\nPlease define in user view")) + gd_client = google.google_login(user_obj.gmail_user,user_obj.gmail_password,type='group') + if not gd_client: + return [('failed', 'Connection to google fail')] + + res = [] + query = gdata.contacts.service.GroupsQuery(feed='/m8/feeds/groups/default/full') + if gd_client: + groups = gd_client.GetFeed(query.ToUri()) + for grp in groups.entry: + res.append((grp.id.text, grp.title.text)) + res.append(('all','All Groups')) + return res + + def _get_calendars(self, cr, uid, context=None): + user_obj = self.pool.get('res.users').browse(cr, uid, uid) + google = self.pool.get('google.login') + res = [] + try: + gd_client = google.google_login(user_obj.gmail_user, user_obj.gmail_password, type='calendar') + calendars = gd_client.GetAllCalendarsFeed() + for cal in calendars.entry: + res.append((cal.id.text, cal.title.text)) + except Exception, e: + return [('failed', 'Connection to google fail')] + res.append(('all', 'All Calendars')) + return res + + _columns = { + 'create_partner': fields.selection([('create_all','Create partner for each contact'),('create_address','Import only address')],'Options'), + 'customer': fields.boolean('Customer', help="Check this box to set newly created partner as Customer."), + 'supplier': fields.boolean('Supplier', help="Check this box to set newly created partner as Supplier."), + 'group_name': fields.selection(_get_group, "Group Name", size=32,help="Choose which group to import, By default it takes all."), + 'calendar_name': fields.selection(_get_calendars, "Calendar Name", size=32), + } + + _defaults = { + 'create_partner': 'create_all', + 'group_name': 'all', + 'calendar_name': 'all', + } + + def import_google(self, cr, uid, ids, context=None): + if context == None: + context = {} + if not ids: + return {'type': 'ir.actions.act_window_close'} + obj = self.browse(cr, uid, ids, context=context)[0] + cust = obj.customer + sup = obj.supplier + tables=[] + user_obj = self.pool.get('res.users').browse(cr, uid, uid) + + gmail_user = user_obj.gmail_user + gmail_pwd = user_obj.gmail_password + google = self.pool.get('google.login') + if not gmail_user or not gmail_pwd: + raise osv.except_osv(_('Error'), _("Invalid login detail !\n Specify Username/Password.")) + + if context.get('contact'): + msg = " You're Contact are import in background, a email will be send when the process is finished to %s"%(user_obj.gmail_user) + gd_client = google.google_login(gmail_user, gmail_pwd, type='contact') + if not gd_client: + raise osv.except_osv(_('Error'), _("Please specify correct user and password !")) + if obj.group_name not in ['all']: + context.update({ 'group_name': obj.group_name}) + if obj.create_partner=='create_all': + tables.append('Contact') + else: + tables.append('Address') + context.update({'user': gmail_user, + 'password': gmail_pwd, + 'instance': 'contact', + 'table':tables, + 'customer':cust, + 'supplier':sup}) + + elif context.get('calendar'): + msg = " You're Meeting are import in background, a email will be send when the process is finished to %s"%(user_obj.gmail_user) + + tables.append('Events') + current_rec = self.browse(cr, uid, ids, context=context) + calendars = False + for rec in current_rec: + if rec.calendar_name != 'all': + calendars = [rec.calendar_name] + else: + calendars = map(lambda x: x[0], [cal for cal in self._get_calendars(cr, uid, context) if cal[0] != 'all']) + context.update({'user': gmail_user, + 'password': gmail_pwd, + 'calendars': calendars, + 'instance': 'calendar'}) + imp = google_import(self, cr, uid,'import_google' , "synchronize_google", gmail_user, context) + imp.set_table_list(tables) + imp.start() + context.update({'message': msg}) + obj_model = self.pool.get('ir.model.data') + model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_google_import_message_form')]) + resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id'] + return { + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'google.import.message', + 'views': [(resource_id,'form')], + 'type': 'ir.actions.act_window', + 'target': 'new', + 'context': context, + } + +synchronize_google() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/import_google/wizard/import_google_data_view.xml b/addons/import_google/wizard/import_google_data_view.xml new file mode 100644 index 00000000000..b35e97645e7 --- /dev/null +++ b/addons/import_google/wizard/import_google_data_view.xml @@ -0,0 +1,91 @@ +<?xml version="1.0"?> +<openerp> + <data> + <record model="ir.ui.view" id="view_synchronize_google_contact_import_form"> + <field name="name">synchronize.base.form</field> + <field name="model">synchronize.google.import</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Import contacts from a google account"> + <group colspan="4" col="4" width="430"> + <field name="group_name" colspan="4"/> + <separator string="Import Options" colspan="4"/> + <field name="create_partner" colspan="4"/> + <newline/> + <group attrs="{'invisible': [('create_partner','!=','create_all')]}" colspan="4" col="4"> + <separator string="Partner status for this group:" colspan="4"/> + <field name="customer" colspan="4"/> + <field name="supplier" colspan="4"/> + </group> + </group> + <separator string="" colspan="4"/> + <group colspan="4" col="4"> + <group colspan="2" col="2"/> + <group colspan="2" col="2"> + <button special="cancel" string="_Cancel" icon="gtk-cancel"/> + <button name="import_google" string="_Import Contacts" type="object" icon="terp-personal+"/> + </group> + </group> + </form> + </field> + </record> + + + + <record model="ir.ui.view" id="view_synchronize_google_calendar_import_form"> + <field name="name">synchronize.google.calendar.form</field> + <field name="model">synchronize.google.import</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Import Google Calendar Events"> + <group colspan="4" col="4" width="320"> + <field name="calendar_name" /> + </group> + <separator string="" colspan="4"/> + <group colspan="4" col="4"> + <group colspan="2" col="2"/> + <group colspan="2" col="2"> + <button special="cancel" string="_Cancel" icon="gtk-cancel"/> + <button name="import_google" string="_Import Events" type="object" icon="terp-calendar"/> + </group> + </group> + </form> + </field> + </record> + <!-- + Login Action + --> + <record model="ir.actions.act_window" id="act_google_login_form"> + <field name="name">Import Google Calendar</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">google.login</field> + <field name="view_type">form</field> + <field name="view_mode">form</field> + <field name="target">new</field> + <field name="context">{'calendar':True}</field> + <field name="view_id" ref="google_base_account.view_google_login_form" /> + </record> + + <record model="ir.actions.act_window" id="act_google_login_contact_form"> + <field name="name">Import Google Contacts</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">google.login</field> + <field name="view_type">form</field> + <field name="view_mode">form</field> + <field name="target">new</field> + <field name="context">{'contact':True}</field> + <field name="view_id" ref="google_base_account.view_google_login_form" /> + </record> + + <menuitem id="menu_sync_contact" + parent="base.menu_address_book" + action="act_google_login_contact_form" + sequence="40" /> + + <menuitem id="menu_sync_calendar" + parent="crm.menu_meeting_sale" + action="act_google_login_form" + sequence="20" /> + + </data> +</openerp> |
