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.gd_client = google.google_login(self.context.get('user'),
51 self.context.get('password'),
52 type = self.context.get('instance'))
53 if self.context.get('instance') and self.context.get('instance') == 'calendar':
54 self.calendars = self.context.get('calendars')
56 def get_mapping(self):
58 self.TABLE_EVENT: self.get_event_mapping(),
61 def get_data(self, table):
63 self.TABLE_EVENT: self.get_events(),
68 def _get_tinydates(self, stime, etime):
69 stime = dateutil.parser.parse(stime)
70 etime = dateutil.parser.parse(etime)
72 au_dt = au_tz.normalize(stime.astimezone(au_tz))
73 timestring = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
74 au_dt = au_tz.normalize(etime.astimezone(au_tz))
75 timestring_end = datetime.datetime(*au_dt.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
77 timestring = datetime.datetime(*stime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
78 timestring_end = datetime.datetime(*etime.timetuple()[:6]).strftime('%Y-%m-%d %H:%M:%S')
79 return (timestring, timestring_end)
81 def _get_rules(self, datas):
83 if datas['FREQ'] == 'WEEKLY' and datas.get('BYDAY'):
84 for day in datas['BYDAY'].split(','):
85 new_val[day.lower()] = True
88 if datas.get('UNTIL'):
89 until = parser.parse(''.join((re.compile('\d')).findall(datas.get('UNTIL'))))
90 new_val['end_date'] = until.strftime('%Y-%m-%d')
91 new_val['end_type'] = 'end_date'
94 if datas.get('COUNT'):
95 new_val['count'] = datas.get('COUNT')
96 new_val['end_type'] = 'count'
99 if datas.get('INTERVAL'):
100 new_val['interval'] = datas.get('INTERVAL')
102 new_val['interval'] = 1
104 if datas.get('BYMONTHDAY'):
105 new_val['day'] = datas.get('BYMONTHDAY')
106 datas.pop('BYMONTHDAY')
107 new_val['select1'] = 'date'
109 if datas.get('BYDAY'):
110 d = datas.get('BYDAY')
112 new_val['byday'] = d[:2]
113 new_val['week_list'] = d[2:4].upper()
115 new_val['byday'] = d[:1]
116 new_val['week_list'] = d[1:3].upper()
117 new_val['select1'] = 'day'
119 if datas.get('BYMONTH'):
120 new_val['month_list'] = datas.get('BYMONTH')
125 def _get_repeat_status(self, str_google):
126 rrule = str_google[str_google.find('FREQ'):str_google.find('\nBEGIN')]
128 for rule in rrule.split(';'):
129 status[rule.split('=')[0]] = rule.split('=')[-1:] and rule.split('=')[-1:][0] or ''
130 rules = self._get_rules(status)
131 if status.get('FREQ') == 'WEEKLY':
132 status.update({'rrule_type': 'weekly'})
134 elif status.get('FREQ') == 'DAILY':
135 status.update({'rrule_type': 'daily'})
137 elif status.get('FREQ') == 'MONTHLY':
138 status.update({'rrule_type': 'monthly'})
140 elif status.get('FREQ') == 'YEARLY':
141 status.update({'rrule_type': 'yearly'})
147 def _get_repeat_dates(self, x):
149 if x[3].startswith('BY'):
150 zone_time = x[4].split('+')[-1:][0].split(':')[0][:4]
152 zone_time = x[3].split('+')[-1:][0].split(':')[0][:4]
154 zone_time = x[2].split('+')[-1:][0].split(':')[0][:4]
155 tz_format = zone_time[:2]+':'+zone_time[2:]
156 repeat_start = x[1].split('\n')[0].split(':')[1]
157 repeat_end = x[2].split('\n')[0].split(':')[1]
158 o = repeat_start.split('T')
159 repeat_start = str(o[0][:4]) + '-' + str(o[0][4:6]) + '-' + str(o[0][6:8])
161 repeat_start += ' ' + str(o[1][:2]) + ':' + str(o[1][2:4]) + ':' + str(o[1][4:6])
163 repeat_start += ' ' + '00' + ':' + '00' + ':' + '00'
164 p = repeat_end.split('T')
165 repeat_end = str(p[0][:4]) + '-' + str(p[0][4:6]) + '-' + str(p[0][6:8])
167 repeat_end += ' ' + str(p[1][:2]) + ':' + str(p[1][2:4]) + ':' + str(p[1][4:6])
169 repeat_end += ' ' + '00' + ':' + '00' + ':' + '00'
170 return (repeat_start, repeat_end, tz_format)
172 def get_events(self):
173 if 'tz' in self.context and self.context['tz']:
174 time_zone = self.context['tz']
176 time_zone = tools.get_server_timezone()
177 au_tz = timezone(time_zone)
179 for cal in self.calendars:
180 events_query = gdata.calendar.service.CalendarEventQuery(user=urllib.unquote(cal.split('/')[~0]))
181 events_query.start_index = 1
182 events_query.max_results = 1000
183 event_feed = self.gd_client.GetCalendarEventFeed(events_query.ToUri())
184 for feed in event_feed.entry:
199 timestring = timestring_end = datetime.datetime.now().strftime(self.DATETIME_FORMAT)
201 timestring, timestring_end = self._get_tinydates(feed.when[0].start_time, feed.when[0].end_time)
203 x = feed.recurrence.text.split(';')
204 repeat_status = self._get_repeat_status(feed.recurrence.text)
205 repeat_start, repeat_end, zone_time = self._get_repeat_dates(x)
206 timestring = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_start, "%Y-%m-%d %H:%M:%S"))
207 timestring_end = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(repeat_end, "%Y-%m-%d %H:%M:%S"))
209 repeat_status.update({'recurrency': True})
210 event.update(repeat_status)
212 event.update({'id' : feed.id.text,
213 'DateStart': timestring,
214 'DateEnd': timestring_end,
215 'Category':event_feed.title.text,
216 'Name': feed.title.text or 'No title',
217 'Description': feed.content.text,
219 event_vals.append(event)
223 def get_event_category(self, val, name):
224 fields = ['name', 'object_id']
225 nameid = 'event_category_'+name
226 data = [name, 'crm.meeting']
227 return self.import_object(fields, data, 'crm.case.categ', "crm_case_categ", nameid, [('name', 'ilike', name)])
229 def get_event(self, val):
230 if val.get("recurrency"):
231 val.update({"recurrency": "1"})
234 def get_event_mapping(self):
236 'model': 'crm.meeting',
237 'hook': self.get_event,
241 'description': 'Description',
242 'email_from': 'Email',
244 'date_deadline': 'DateEnd',
245 'categ_id/id': call(self.get_event_category, value('Category')),
246 'recurrency': 'recurrency',
247 'end_date' : 'end_date',
248 'end_type' : 'end_type',
251 'interval': 'interval',
254 'week_list': 'week_list',
255 'month_list':'month_list',
256 'rrule_type': 'rrule_type',