Merge lp:~minakov/calendar-indicator/all-calendars into lp:calendar-indicator/precise

Proposed by Vladimir Minakov
Status: Needs review
Proposed branch: lp:~minakov/calendar-indicator/all-calendars
Merge into: lp:calendar-indicator/precise
Diff against target: 405 lines (+243/-75)
3 files modified
src/calendar-indicator.py (+51/-73)
src/comun.py (+2/-2)
src/googlecalendar.py (+190/-0)
To merge this branch: bzr merge lp:~minakov/calendar-indicator/all-calendars
Reviewer Review Type Date Requested Status
atareao-team Pending
Review via email: mp+95446@code.launchpad.net

Description of the change

support all calendars

To post a comment you must log in.
19. By Vladimir Minakov

Fix bugs

Unmerged revisions

19. By Vladimir Minakov

Fix bugs

18. By Vladimir Minakov

All calendars

17. By Vladimir Minakov

All calendars

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/calendar-indicator.py'
--- src/calendar-indicator.py 2012-02-19 20:33:42 +0000
+++ src/calendar-indicator.py 2012-03-01 20:44:18 +0000
@@ -44,7 +44,7 @@
44#44#
45import comun45import comun
46from configurator import Configuration46from configurator import Configuration
47from gcal import GCal47from googlecalendar import GoogleCalendar
48from preferences_dialog import Preferences48from preferences_dialog import Preferences
49#49#
50locale.setlocale(locale.LC_ALL, '')50locale.setlocale(locale.LC_ALL, '')
@@ -52,29 +52,9 @@
52gettext.textdomain(comun.APP)52gettext.textdomain(comun.APP)
53_ = gettext.gettext53_ = gettext.gettext
5454
55def internet_on():
56 try:
57 response=urllib2.urlopen('http://google.com',timeout=1)
58 return True
59 except:
60 pass
61 return False
62
63
64def getTimeAndDate(cadena):
65 if cadena.find('T')==-1:
66 date = cadena.split('-')
67 time = datetime.time(0,0,0)
68 else:
69 date = cadena.split('T')[0].split('-')
70 time = cadena.split('T')[1].split(':')
71 time = datetime.time(int(time[0]),int(time[1]),int(time[2][0:2]))
72 date = datetime.date(int(date[0]),int(date[1]),int(date[2]))
73 return date.strftime('%d/%m/%Y')+' - '+time.strftime('%H:%M')
74
75def check_events(event1,event2):55def check_events(event1,event2):
76 if event1.when[0].start == event2.when[0].start:56 if event1.when[0].start_time == event2.when[0].start_time:
77 if event1.when[0].end == event2.when[0].end:57 if event1.when[0].end_time == event2.when[0].end_time:
78 if event1.title.text == event2.title.text:58 if event1.title.text == event2.title.text:
79 return True59 return True
80 return False60 return False
@@ -119,6 +99,8 @@
119 self.read_preferences()99 self.read_preferences()
120 #100 #
121 self.events = []101 self.events = []
102 self.load_events()
103 self.set_icon()
122 self.set_menu()104 self.set_menu()
123 GObject.timeout_add_seconds(60, self.work)105 GObject.timeout_add_seconds(60, self.work)
124106
@@ -127,7 +109,7 @@
127 while error:109 while error:
128 try:110 try:
129 configuration = Configuration()111 configuration = Configuration()
130 self.gcal=GCal(configuration.get('user'), configuration.get('password'))112 self.gcal = GoogleCalendar(configuration.get('user'), configuration.get('password'))
131 self.time = configuration.get('time')113 self.time = configuration.get('time')
132 self.theme = configuration.get('theme')114 self.theme = configuration.get('theme')
133 error = False115 error = False
@@ -153,45 +135,53 @@
153135
154 def work(self):136 def work(self):
155 if (time.time()-self.actualization_time) > self.time*60:137 if (time.time()-self.actualization_time) > self.time*60:
156 while internet_on() == False:138 try:
157 time.sleep(1)139 self.load_events(True)
158 self.actualization_time = time.time()140 except Exception, e:
159 self.set_menu(check=True)141 print e
142 return True
143 self.set_icon()
144 self.set_menu()
160 return True145 return True
161146
162 def set_menu(self,check=False):147 def load_events(self,check=False):
163 #148 new_events = self.gcal.AgendaQuery()
149
150 if check:
151 for event in new_events:
152 if not is_event_in_events(event, self.events):
153 msg = event.s.strftime('%d/%m/%Y - %H:%M') + ' - ' + event.title.text
154 self.notification = Notify.Notification.new(_('New event:'), msg, comun.ICON_NEW_EVENT)
155 self.notification.show()
156 for event in self.events:
157 if not is_event_in_events(event, new_events):
158 msg = event.s.strftime('%d/%m/%Y - %H:%M') + ' - ' + event.title.text
159 self.notification = Notify.Notification.new(_('Event finished:'), msg, comun.ICON_FINISHED_EVENT)
160 self.notification.show()
161
162 self.events = new_events
163 self.actualization_time = time.time()
164
165 def set_icon(self):
164 now = datetime.datetime.now()166 now = datetime.datetime.now()
165 normal_icon = os.path.join(comun.ICONDIR,'%s-%s-normal.svg'%(now.day,self.theme))167 normal_icon = os.path.join(comun.ICONDIR, '%s-%s-normal.svg' % (now.day, self.theme))
166 starred_icon = os.path.join(comun.ICONDIR,'%s-%s-starred.svg'%(now.day,self.theme))168 starred_icon = os.path.join(comun.ICONDIR, '%s-%s-starred.svg' % (now.day, self.theme))
167 #169 #
168 self.indicator.set_icon(normal_icon)170 self.indicator.set_icon(normal_icon)
169 self.indicator.set_attention_icon(starred_icon) 171 self.indicator.set_attention_icon(starred_icon)
170 #self.indicator.set_icon(comun.ICON_ENABLED)172 #self.indicator.set_icon(comun.ICON_ENABLED)
171 #self.indicator.set_attention_icon(comun.ICON_DISABLED) 173 #self.indicator.set_attention_icon(comun.ICON_DISABLED)
172 #174
175 if self._has_today(now):
176 self.indicator.set_status(appindicator.IndicatorStatus.ATTENTION)
177 else:
178 self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
179
180 def set_menu(self):
173 self.menu = Gtk.Menu()181 self.menu = Gtk.Menu()
174 #182 #
175 events2 = self.gcal.getFirstTenEventsOnDefaultCalendar()
176 if check and len(self.events)>0:
177 for event in events2:
178 if not is_event_in_events(event,self.events):
179 msg = _('New event:')+'\n'
180 msg += getTimeAndDate(event.when[0].start)+' - '+event.title.text
181 print msg
182 self.notification = Notify.Notification ('Calendar Indicator',msg,comun.ICON_NEW_EVENT)
183 self.notification.show()
184 for event in self.events:
185 if not is_event_in_events(event,events2):
186 msg = _('Event finished:')+'\n'
187 msg += getTimeAndDate(event.when[0].start)+' - '+event.title.text
188 print msg
189 self.notification = Notify.Notification ('Calendar Indicator',msg,comun.ICON_FINISHED_EVENT)
190 self.notification.show()
191
192 self.events = events2
193 for event in self.events:183 for event in self.events:
194 add2menu(self.menu, text = (getTimeAndDate(event.when[0].start)+' - '+event.title.text))184 add2menu(self.menu, text = (event.s.strftime('%d/%m/%Y - %H:%M') + ' - ' + event.title.text))
195 #185 #
196 add2menu(self.menu)186 add2menu(self.menu)
197 self.menu_show_calendar = add2menu(self.menu, text = _('Show Calendar'), conector_event = 'activate',conector_action = self.menu_show_calendar_response)187 self.menu_show_calendar = add2menu(self.menu, text = _('Show Calendar'), conector_event = 'activate',conector_action = self.menu_show_calendar_response)
@@ -202,29 +192,11 @@
202 add2menu(self.menu)192 add2menu(self.menu)
203 add2menu(self.menu, text = _('Exit'), conector_event = 'activate',conector_action = self.menu_exit_response)193 add2menu(self.menu, text = _('Exit'), conector_event = 'activate',conector_action = self.menu_exit_response)
204 #194 #
205 now = datetime.datetime.now()
206 if self.events[0].when[0].start.find('T') != -1:
207 print self.events[0].when[0].start
208 if self.events[0].when[0].start.find('.') != -1:
209 com = datetime.datetime.strptime(self.events[0].when[0].start.split('.')[0],'%Y-%m-%dT%H:%M:%S')
210 else:
211 com = datetime.datetime.strptime(self.events[0].when[0].start,'%Y-%m-%dT%H:%M:%S')
212
213 else:
214 com = datetime.datetime.strptime(self.events[0].when[0].start,'%Y-%m-%d')
215 if now.year == com.year and now.month == com.month and now.day == com.day and now.hour == com.hour:
216 self.indicator.set_status (appindicator.IndicatorStatus.ATTENTION)
217 else:
218 print now.hour
219 print com.hour
220 print self.events[0].when[0].start
221 self.indicator.set_status (appindicator.IndicatorStatus.ACTIVE)
222 #
223 self.menu.show()195 self.menu.show()
224 self.indicator.set_menu(self.menu)196 self.indicator.set_menu(self.menu)
197 #
225 while Gtk.events_pending():198 while Gtk.events_pending():
226 Gtk.main_iteration()199 Gtk.main_iteration()
227
228200
229 def get_help_menu(self):201 def get_help_menu(self):
230 help_menu =Gtk.Menu()202 help_menu =Gtk.Menu()
@@ -250,7 +222,7 @@
250 while error:222 while error:
251 try:223 try:
252 configuration = Configuration()224 configuration = Configuration()
253 self.gcal=GCal(configuration.get('user'), configuration.get('password'))225 self.gcal=GoogleCalendar(configuration.get('user'), configuration.get('password'))
254 self.time = configuration.get('time')226 self.time = configuration.get('time')
255 self.theme = configuration.get('theme')227 self.theme = configuration.get('theme')
256 error = False228 error = False
@@ -311,6 +283,12 @@
311 ad.run()283 ad.run()
312 ad.destroy()284 ad.destroy()
313 self.menu_about.set_sensitive(True)285 self.menu_about.set_sensitive(True)
286
287 def _has_today(self, today):
288 for event in self.events:
289 if today.year == event.s.year and today.month == event.s.month and today.day == event.s.day and today.hour == event.s.hour:
290 return True
291 return False
314292
315if __name__ == "__main__":293if __name__ == "__main__":
316 Notify.init("calendar-indicator")294 Notify.init("calendar-indicator")
317295
=== modified file 'src/comun.py'
--- src/comun.py 2012-02-19 20:33:42 +0000
+++ src/comun.py 2012-03-01 20:44:18 +0000
@@ -60,5 +60,5 @@
60 APPDIR = os.path.join(ROOTDIR, APP)60 APPDIR = os.path.join(ROOTDIR, APP)
61 ICONDIR = os.path.join(ROOTDIR, 'data/icons')61 ICONDIR = os.path.join(ROOTDIR, 'data/icons')
6262
63ICON_NEW_EVENT = 'event-new'63ICON_NEW_EVENT = os.path.join(ICONDIR, 'event-new.svg')
64ICON_FINISHED_EVENT = 'event-finished'64ICON_FINISHED_EVENT = os.path.join(ICONDIR, 'event-finished.svg')
6565
=== added file 'src/googlecalendar.py'
--- src/googlecalendar.py 1970-01-01 00:00:00 +0000
+++ src/googlecalendar.py 2012-03-01 20:44:18 +0000
@@ -0,0 +1,190 @@
1#! /usr/bin/python
2# -*- coding: iso-8859-15 -*-
3#
4__author__='atareao'
5__date__ ='$30/10/2010'
6#
7# Copyright (C) 2010 Lorenzo Carbonell
8# lorenzo.carbonell.cerezo@gmail.com
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.
22#
23import sys, re, urllib, getopt
24import threading, getpass
25from Queue import Queue
26from gdata.calendar.service import *
27from datetime import *
28from dateutil.tz import *
29from dateutil.parser import *
30
31class GoogleCalendar(object):
32 allCals = None
33 cals = []
34 now = datetime.now(tzlocal())
35 agendaLength = 30
36
37 def __init__(self,email,password):
38 self.email = email
39 self.password = password
40 self.client = CalendarService()
41 self.client.ClientLogin(self.email,self.password, 'calendar-indicator')
42
43 # get the list of calendars
44 self.allCals = self.client.GetAllCalendarsFeed()
45 for cal in self.allCals.entry:
46 cal.gcalcli_altLink = cal.GetAlternateLink().href
47 match = re.match('^https?://www.google.com/calendar/feeds/(.*?)/(.*?)/(.*)$', cal.gcalcli_altLink)
48 cal.gcalcli_username = urllib.unquote(match.group(1))
49 cal.gcalcli_visibility = urllib.unquote(match.group(2))
50 cal.gcalcli_projection = urllib.unquote(match.group(3))
51 self.cals.append(cal)
52
53 def AgendaQuery(self):
54 start = self.now
55 end = (start + timedelta(days=self.agendaLength))
56 return self._SearchForCalEvents(start, end, None)
57
58 def _SearchForCalEvents(self, start, end, searchText):
59 eventList = []
60 queue = Queue()
61 threads = []
62
63 def worker(cal, query):
64 feed = self.client.CalendarQuery(query)
65 queue.put((cal, feed))
66
67 for cal in self.cals:
68 # see http://code.google.com/apis/calendar/reference.html
69 if not searchText:
70 query = CalendarEventQuery(cal.gcalcli_username, cal.gcalcli_visibility, cal.gcalcli_projection)
71 query.start_min = start.isoformat()
72 query.start_max = end.isoformat()
73 else:
74 query = CalendarEventQuery(cal.gcalcli_username, cal.gcalcli_visibility, cal.gcalcli_projection, searchText)
75 if start: # flagged by --ignore-started
76 # weeds out old but still pulls in started events
77 query.futureevents = 'true'
78
79 query.singleevents = 'true'
80
81 # we sort later after getting events from all calendars
82 #query.orderby = 'starttime'
83 #query.sortorder = 'ascending'
84
85 th = threading.Thread(target=worker, args=(cal, query))
86 threads.append(th)
87 th.start()
88
89 for th in threads:
90 th.join()
91
92 while not queue.empty():
93 cal, feed = queue.get()
94 eventList.extend(self._GetAllEvents(cal, feed, end))
95
96 eventList.sort(lambda x, y: cmp(x.s, y.s))
97
98 return eventList
99
100 def _GetAllEvents(self, cal, feed, end):
101 eventList = []
102
103 while 1:
104 next = feed.GetNextLink()
105
106 for event in feed.entry:
107 event.gcalcli_cal = cal
108
109 event.s = parse(event.when[0].start_time)
110 if event.s.tzinfo == None:
111 event.s = event.s.replace(tzinfo=tzlocal())
112
113 event.e = parse(event.when[0].end_time)
114 if event.e.tzinfo == None:
115 event.e = event.e.replace(tzinfo=tzlocal())
116
117 # For all-day events, Google seems to assume that the event time
118 # is based in the UTC instead of the local timezone. Here we
119 # filter out those events start beyond a specified end time.
120 if end and (event.s >= end):
121 continue
122
123 # http://en.wikipedia.org/wiki/Year_2038_problem
124 # Catch the year 2038 problem here as the python dateutil module
125 # can choke throwing a ValueError exception. If either the start
126 # or end time for an event has a year '>= 2038' dump it.
127 if event.s.year >= 2038 or event.e.year >= 2039:
128 continue
129
130 eventList.append(event)
131
132 if not next:
133 break
134
135 feed = self.client.GetCalendarEventFeed(next.href)
136
137 return eventList
138
139 def _ValidTitle(self, title):
140 if title == None:
141 return "(No title)"
142 else:
143 return title
144
145 def _CalendarColor(self, cal):
146 if cal != None and hasattr(cal, 'colorSpec') and cal.colorSpec != None:
147 return cal.colorSpec
148 else:
149 return None
150
151if __name__ == '__main__':
152 try:
153 opts, args = getopt.getopt(sys.argv[1:], "", [ "user=","pw=" ])
154 except getopt.error:
155 sys.exit(1)
156
157 usr = None
158 pwd = None
159
160 for opt, arg in opts:
161 if opt == "--user":
162 usr = arg
163 elif opt == "--pw":
164 pwd = arg
165
166 if usr == None:
167 sys.stdout.write('Error: must specify a username\n')
168 sys.exit(1)
169
170 try:
171 if pwd == None:
172 pwd = getpass.getpass("Password: ")
173 except Exception, e:
174 sys.stdout.write("Error: " + str(e) + "!\n")
175 sys.exit(1)
176
177 if pwd == None or pwd == '':
178 sys.stdout.write('Error: must specify a password\n')
179 sys.exit(1)
180
181 try:
182 gcal = GoogleCalendar(usr, pwd)
183 except Exception, e:
184 sys.stdout.write("Error: " + str(e) + "!\n")
185 sys.exit(1)
186
187 for event in gcal.AgendaQuery():
188 print event.title.text
189
190 sys.exit(0)

Subscribers

People subscribed via source and target branches

to all changes: