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 ##############################################################################
25 from dateutil import *
26 from pytz import timezone
27 from datetime import datetime
31 import gdata.contacts.service
32 import gdata.calendar.service
36 raise osv.except_osv(_('Google Contacts Import Error!'), _('Please install gdata-python-client from http://code.google.com/p/gdata-python-client/downloads/list'))
37 from import_base.import_framework import *
38 from import_base.mapper import *
40 class import_contact(import_framework):
44 DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
45 TABLE_CONTACT = 'contact'
46 TABLE_EVENT = 'Events'
49 google = self.obj.pool.get('google.login')
50 self.external_id_field = 'Id'
51 self.gclient=self.context.get('gd_client', False)
52 self.gd_client = google.google_login(self.context.get('user'),
53 self.context.get('password'),
54 type = self.context.get('instance'))
55 if self.context.get('instance') and self.context.get('instance') == 'calendar':
56 self.calendars = self.context.get('calendars')
58 def get_mapping(self):
60 self.TABLE_EVENT: self.get_event_mapping(),
61 self.TABLE_CONTACT: self.get_contact_mapping(),
62 self.TABLE_ADDRESS: self.get_address_mapping(),
65 def get_data(self, table):
67 self.TABLE_EVENT: self.get_events(),
68 self.TABLE_CONTACT: self.get_contact(),
73 def _get_tinydates(self, stime, etime):
74 stime = dateutil.parser.parse(stime)
75 etime = dateutil.parser.parse(etime)
77 au_dt = au_tz.normalize(stime.astimezone(au_tz))
78 timestring = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
79 au_dt = au_tz.normalize(etime.astimezone(au_tz))
80 timestring_end = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
82 timestring = datetime.datetime(*stime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
83 timestring_end = datetime.datetime(*etime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
84 return (timestring, timestring_end)
86 def _get_rules(self, datas):
88 if datas['FREQ'] == 'WEEKLY' and datas.get('BYDAY'):
89 for day in datas['BYDAY'].split(','):
90 new_val[day.lower()] = True
93 if datas.get('UNTIL'):
94 until = parser.parse(''.join((re.compile('\d')).findall(datas.get('UNTIL'))))
95 new_val['end_date'] = until.strftime('%Y-%m-%d')
96 new_val['end_type'] = 'end_date'
99 if datas.get('COUNT'):
100 new_val['count'] = datas.get('COUNT')
101 new_val['end_type'] = 'count'
104 if datas.get('INTERVAL'):
105 new_val['interval'] = datas.get('INTERVAL')
107 new_val['interval'] = 1
109 if datas.get('BYMONTHDAY'):
110 new_val['day'] = datas.get('BYMONTHDAY')
111 datas.pop('BYMONTHDAY')
112 new_val['select1'] = 'date'
114 if datas.get('BYDAY'):
115 d = datas.get('BYDAY')
117 new_val['byday'] = d[:2]
118 new_val['week_list'] = d[2:4].upper()
120 new_val['byday'] = d[:1]
121 new_val['week_list'] = d[1:3].upper()
122 new_val['select1'] = 'day'
124 if datas.get('BYMONTH'):
125 new_val['month_list'] = datas.get('BYMONTH')
130 def _get_repeat_status(self, str_google):
131 rrule = str_google[str_google.find('FREQ'):str_google.find('\nBEGIN')]
133 for rule in rrule.split(';'):
134 status[rule.split('=')[0]] = rule.split('=')[-1:] and rule.split('=')[-1:][0] or ''
135 rules = self._get_rules(status)
136 if status.get('FREQ') == 'WEEKLY':
137 status.update({'rrule_type': 'weekly'})
139 elif status.get('FREQ') == 'DAILY':
140 status.update({'rrule_type': 'daily'})
142 elif status.get('FREQ') == 'MONTHLY':
143 status.update({'rrule_type': 'monthly'})
145 elif status.get('FREQ') == 'YEARLY':
146 status.update({'rrule_type': 'yearly'})
152 def _get_repeat_dates(self, x):
154 if x[3].startswith('BY'):
155 zone_time = x[4].split('+')[-1:][0].split(':')[0][:4]
157 zone_time = x[3].split('+')[-1:][0].split(':')[0][:4]
159 zone_time = x[2].split('+')[-1:][0].split(':')[0][:4]
160 tz_format = zone_time[:2]+':'+zone_time[2:]
161 repeat_start = x[1].split('\n')[0].split(':')[1]
162 repeat_end = x[2].split('\n')[0].split(':')[1]
163 o = repeat_start.split('T')
164 repeat_start = str(o[0][:4]) + '-' + str(o[0][4:6]) + '-' + str(o[0][6:8])
166 repeat_start += ' ' + str(o[1][:2]) + ':' + str(o[1][2:4]) + ':' + str(o[1][4:6])
168 repeat_start += ' ' + '00' + ':' + '00' + ':' + '00'
169 p = repeat_end.split('T')
170 repeat_end = str(p[0][:4]) + '-' + str(p[0][4:6]) + '-' + str(p[0][6:8])
172 repeat_end += ' ' + str(p[1][:2]) + ':' + str(p[1][2:4]) + ':' + str(p[1][4:6])
174 repeat_end += ' ' + '00' + ':' + '00' + ':' + '00'
175 return (repeat_start, repeat_end, tz_format)
177 def get_events(self):
178 if 'tz' in self.context and self.context['tz']:
179 time_zone = self.context['tz']
181 time_zone = tools.get_server_timezone()
182 au_tz = timezone(time_zone)
184 for cal in self.calendars:
185 events_query = gdata.calendar.service.CalendarEventQuery(user=urllib.unquote(cal.split('/')[~0]))
186 events_query.start_index = 1
187 events_query.max_results = 1000
188 event_feed = self.gd_client.GetCalendarEventFeed(events_query.ToUri())
189 for feed in event_feed.entry:
204 timestring = timestring_end = datetime.datetime.now().strftime(self.DATETIME_FORMAT)
206 timestring, timestring_end = self._get_tinydates(feed.when[0].start_time, feed.when[0].end_time)
208 x = feed.recurrence.text.split(';')
209 repeat_status = self._get_repeat_status(feed.recurrence.text)
210 repeat_start, repeat_end, zone_time = self._get_repeat_dates(x)
211 timestring = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_start, "%Y-%m-%d %H:%M:%S"))
212 timestring_end = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_end, "%Y-%m-%d %H:%M:%S"))
214 repeat_status.update({'recurrency': True})
215 event.update(repeat_status)
217 event.update({'id' : feed.id.text,
218 'DateStart': timestring,
219 'DateEnd': timestring_end,
220 'Category':event_feed.title.text,
221 'Name': feed.title.text or 'No title',
222 'Description': feed.content.text,
224 event_vals.append(event)
228 def get_event_category(self, val, name):
229 fields = ['name', 'object_id']
230 nameid = 'event_category_'+name
231 data = [name, 'crm.meeting']
232 return self.import_object(fields, data, 'crm.case.categ', "crm_case_categ", nameid, [('name', 'ilike', name)])
234 def get_event(self, val):
235 if val.get("recurrency"):
236 val.update({"recurrency": "1"})
239 def get_event_mapping(self):
241 'model': 'crm.meeting',
242 'hook': self.get_event,
246 'description': 'Description',
247 'email_from': 'Email',
249 'date_deadline': 'DateEnd',
250 'categ_id/id': call(self.get_event_category, value('Category')),
251 'recurrency': 'recurrency',
252 'end_date' : 'end_date',
253 'end_type' : 'end_type',
256 'interval': 'interval',
259 'week_list': 'week_list',
260 'month_list':'month_list',
261 'rrule_type': 'rrule_type',
266 def get_contact(self):
268 gclient=self.context.get('client',False)
271 for entry in contact.entry:
273 data['id'] = entry.id.text
274 name = tools.ustr(entry.title.text)
276 name = entry.email[0].address
278 emails = ','.join(email.address for email in entry.email)
279 data['email'] = emails
280 if entry.organization:
281 if entry.organization.org_name:
282 data.update({'company': entry.organization.org_name.text})
283 if entry.organization.org_title:
284 data.update ({'function': entry.organization.org_title.text})
285 if entry.phone_number:
286 for phone in entry.phone_number:
287 if phone.rel == gdata.contacts.REL_WORK:
288 data['phone'] = phone.text
289 if phone.rel == gdata.contacts.PHONE_MOBILE:
290 data['mobile'] = phone.text
291 if phone.rel == gdata.contacts.PHONE_WORK_FAX:
292 data['fax'] = phone.text
294 next = contact.GetNextLink()
295 contact = next and gclient.GetContactsFeed(next.href) or None
299 def get_partner_address(self,val):
309 val.update({'Type':'contact'})
310 val.update({'id_new': val['id']+'address_contact' })
311 return self.import_object_mapping(field_map , val, 'res.partner.address', self.context.get('table')[0], val['id_new'], self.DO_NOT_FIND_DOMAIN)
313 def get_contact_mapping(self):
315 'model': 'res.partner',
319 'customer': str(self.context.get('customer')),
320 'supplier': str(self.context.get('supplier')),
321 'address/id': self.get_partner_address,
325 def get_address_mapping(self):
326 print"RRRRRRRRRREEElated to Address ONLY......................"
328 'model': 'res.partner.address',