diff options
Diffstat (limited to 'addons/import_google/wizard/import_google.py')
| -rw-r--r-- | addons/import_google/wizard/import_google.py | 355 |
1 files changed, 355 insertions, 0 deletions
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' + } + + } |
