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
35 raise osv.except_osv(_('Google Contacts Import Error!'), _('Please install gdata-python-client from http://code.google.com/p/gdata-python-client/downloads/list'))
36 from import_base.import_framework import *
37 from import_base.mapper import *
39 class import_contact(import_framework):
41 gd_calendar_client = False
43 DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
44 TABLE_CONTACT = 'contact'
45 TABLE_EVENT = 'Events'
48 if 'events' in self.context and self.context.get('events'):
49 self.gd_calendar_client = gdata.calendar.service.CalendarService()
50 self.gd_calendar_client.ClientLogin(self.context.get('user', False),self.context.get('password', False))
51 self.calendars = self.context.get('calendars')
53 def get_mapping(self):
55 self.TABLE_EVENT: self.get_event_mapping(),
58 def get_data(self, table):
60 self.TABLE_EVENT: self.get_events(),
65 def _get_tinydates(self, stime, etime):
66 stime = dateutil.parser.parse(stime)
67 etime = dateutil.parser.parse(etime)
69 au_dt = au_tz.normalize(stime.astimezone(au_tz))
70 timestring = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
71 au_dt = au_tz.normalize(etime.astimezone(au_tz))
72 timestring_end = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
74 timestring = datetime.datetime(*stime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
75 timestring_end = datetime.datetime(*etime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
76 return (timestring, timestring_end)
78 def _get_rules(self, datas):
80 if datas['FREQ'] == 'WEEKLY' and datas.get('BYDAY'):
81 for day in datas['BYDAY'].split(','):
82 new_val[day.lower()] = True
85 if datas.get('UNTIL'):
86 until = parser.parse(''.join((re.compile('\d')).findall(datas.get('UNTIL'))))
87 new_val['end_date'] = until.strftime('%Y-%m-%d')
88 new_val['end_type'] = 'end_date'
91 if datas.get('COUNT'):
92 new_val['count'] = datas.get('COUNT')
93 new_val['end_type'] = 'count'
96 if datas.get('INTERVAL'):
97 new_val['interval'] = datas.get('INTERVAL')
99 new_val['interval'] = 1
101 if datas.get('BYMONTHDAY'):
102 new_val['day'] = datas.get('BYMONTHDAY')
103 datas.pop('BYMONTHDAY')
104 new_val['select1'] = 'date'
106 if datas.get('BYDAY'):
107 d = datas.get('BYDAY')
109 new_val['byday'] = d[:2]
110 new_val['week_list'] = d[2:4].upper()
112 new_val['byday'] = d[:1]
113 new_val['week_list'] = d[1:3].upper()
114 new_val['select1'] = 'day'
116 if datas.get('BYMONTH'):
117 new_val['month_list'] = datas.get('BYMONTH')
122 def _get_repeat_status(self, str_google):
123 rrule = str_google[str_google.find('FREQ'):str_google.find('\nBEGIN')]
125 for rule in rrule.split(';'):
126 status[rule.split('=')[0]] = rule.split('=')[-1:] and rule.split('=')[-1:][0] or ''
127 rules = self._get_rules(status)
128 if status.get('FREQ') == 'WEEKLY':
129 status.update({'rrule_type': 'weekly'})
131 elif status.get('FREQ') == 'DAILY':
132 status.update({'rrule_type': 'daily'})
134 elif status.get('FREQ') == 'MONTHLY':
135 status.update({'rrule_type': 'monthly'})
137 elif status.get('FREQ') == 'YEARLY':
138 status.update({'rrule_type': 'yearly'})
144 def _get_repeat_dates(self, x):
146 if x[3].startswith('BY'):
147 zone_time = x[4].split('+')[-1:][0].split(':')[0][:4]
149 zone_time = x[3].split('+')[-1:][0].split(':')[0][:4]
151 zone_time = x[2].split('+')[-1:][0].split(':')[0][:4]
152 tz_format = zone_time[:2]+':'+zone_time[2:]
153 repeat_start = x[1].split('\n')[0].split(':')[1]
154 repeat_end = x[2].split('\n')[0].split(':')[1]
155 o = repeat_start.split('T')
156 repeat_start = str(o[0][:4]) + '-' + str(o[0][4:6]) + '-' + str(o[0][6:8])
158 repeat_start += ' ' + str(o[1][:2]) + ':' + str(o[1][2:4]) + ':' + str(o[1][4:6])
160 repeat_start += ' ' + '00' + ':' + '00' + ':' + '00'
161 p = repeat_end.split('T')
162 repeat_end = str(p[0][:4]) + '-' + str(p[0][4:6]) + '-' + str(p[0][6:8])
164 repeat_end += ' ' + str(p[1][:2]) + ':' + str(p[1][2:4]) + ':' + str(p[1][4:6])
166 repeat_end += ' ' + '00' + ':' + '00' + ':' + '00'
167 return (repeat_start, repeat_end, tz_format)
169 def get_events(self):
170 if 'tz' in self.context and self.context['tz']:
171 time_zone = self.context['tz']
173 time_zone = tools.get_server_timezone()
174 au_tz = timezone(time_zone)
176 for cal in self.calendars:
177 events_query = gdata.calendar.service.CalendarEventQuery(user=urllib.unquote(cal.split('/')[~0]))
178 events_query.start_index = 1
179 events_query.max_results = 1000
180 event_feed = self.gd_calendar_client.GetCalendarEventFeed(events_query.ToUri())
181 for feed in event_feed.entry:
196 timestring = timestring_end = datetime.datetime.now().strftime(self.DATETIME_FORMAT)
198 timestring, timestring_end = self._get_tinydates(feed.when[0].start_time, feed.when[0].end_time)
200 x = feed.recurrence.text.split(';')
201 repeat_status = self._get_repeat_status(feed.recurrence.text)
202 repeat_start, repeat_end, zone_time = self._get_repeat_dates(x)
203 timestring = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_start, "%Y-%m-%d %H:%M:%S"))
204 timestring_end = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_end, "%Y-%m-%d %H:%M:%S"))
206 repeat_status.update({'recurrency': True})
207 event.update(repeat_status)
209 event.update({'id' : feed.id.text,
210 'DateStart': timestring,
211 'DateEnd': timestring_end,
212 'Category':event_feed.title.text,
213 'Name': feed.title.text or 'No title',
214 'Description': feed.content.text,
216 event_vals.append(event)
220 def get_event_category(self, val, name):
221 fields = ['name', 'object_id']
222 nameid = 'event_category_'+name
223 data = [name, 'crm.meeting']
224 return self.import_object(fields, data, 'crm.case.categ', "crm_case_categ", nameid, [('name', 'ilike', name)])
226 def get_event(self, val):
227 if val.get("recurrency"):
228 val.update({"recurrency": "1"})
231 def get_event_mapping(self):
233 'model': 'crm.meeting',
234 'hook': self.get_event,
238 'description': 'Description',
239 'email_from': 'Email',
241 'date_deadline': 'DateEnd',
242 'categ_id/id': call(self.get_event_category, value('Category')),
243 'recurrency': 'recurrency',
244 'end_date' : 'end_date',
245 'end_type' : 'end_type',
248 'interval': 'interval',
251 'week_list': 'week_list',
252 'month_list':'month_list',
253 'rrule_type': 'rrule_type',