#!/usr/bin/env python # -*- coding: utf-8 -*- # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # (C) 2010 boamaod@gmail.com, saweden@hotmail.com # # Provided by the gCal Screenlet Team # # Originally based on and inspired by the GDocs Screenlet by Alexandre freret # and eventcal/eigencal screenlet by Lukas K. and Wolfgang Arlt # # Using modified Google icon from FREE Handy Icon Set by Webdesigner Depot # http://www.webdesignerdepot.com/2009/04/24-free-exclusive-vector-icons-handy/ # # INFO: # This screenlet puts your Google calendar on your desktop. # import screenlets from screenlets.options import StringOption , BoolOption , IntOption , FileOption , DirectoryOption , ListOption , AccountOption , TimeOption , FontOption, ColorOption , ImageOption, FloatOption from screenlets.options import create_option_from_node from screenlets import DefaultMenuItem import cairo import pango import gobject import threading import traceback import gtk import time import datetime import pygtk pygtk.require('2.0') import sys import locale import re import urllib from operator import itemgetter import os import string import math try: import gdata.calendar.service import gdata.service import atom.service import gdata.calendar import atom except: print "Importing gdata failed." X_SIZE = 440 Y_SIZE = 155 # use gettext for translation import gettext _ = screenlets.utils.get_translator(__file__) def tdoc(obj): obj.__doc__ = _(obj.__doc__) return obj class Updater(threading.Thread): dealingWithData = False __lock = threading.Lock() screenlet = None def __init__(self, screenlet): threading.Thread.__init__(self) self.screenlet = screenlet def run ( self ): if not self.dealingWithData: self.dealingWithData = True threading.Thread(target=self.__deal_with_data).start() def __deal_with_data(self): """Retrieves the list of calendars to which the authenticated user either owns or subscribes to. This is the same list as is represented in the Google Calendar GUI. Although we are only printing the title of the calendar in this case, other information, including the color of the calendar, the timezone, and more. See CalendarListEntry for more details on available attributes.""" err = False # print "ALGAS ANDMETEGA TEGELEMINE..." try: self.__lock.acquire() if self.screenlet.cal_client is None: print "No client" return if self.screenlet.connected: self.screenlet.calendarevents = [ ] sig = "+" if time.timezone >= 0: sig = "-" ttt = sig + string.zfill(abs(time.timezone)/3600, 2) + ":" + string.zfill(abs(time.timezone)/3600*6, 2) #ttt="+5:30" #start_date='2010-05-24T00:00:00+09:00', end_date='2010-05-24T23:59:59+09:00' __first_date_to_fetch = str(datetime.date.today())+"T00:00:00" + ttt __last_date_to_fetch = str(datetime.date.today()+ datetime.timedelta(days=self.screenlet.eventDaysToShow)) + "T23:59:59" + ttt print __first_date_to_fetch,__last_date_to_fetch,self.screenlet.eventDaysToShow #__first_date_to_fetch="2011-09-09T00:00:00+05:30" #__last_date_to_fetch ="2011-09-17T00:00:00+05:30" # from datetime import datetime todaysdate = datetime.datetime.now() start_datetime_fetch = datetime.datetime(todaysdate.year, todaysdate.month, todaysdate.day) print 'Fetching events in calendars from: %s to %s.' % (__first_date_to_fetch, __last_date_to_fetch,) all_calendars_feed = self.screenlet.cal_client.GetAllCalendarsFeed() print 'Printing allcalendars: %s' % all_calendars_feed.title.text # for i, a_calendar in zip(xrange(len(all_calendars_feed.entry)), all_calendars_feed.entry): # print '%s. %s' % (i, a_calendar.title.text,) #Now loop through all of the CalendarListEntry items. for (index, cal) in enumerate(all_calendars_feed.entry): print "----------------------------------" if (cal.hidden.value == "true"): print "Calendar %s is hidden. Events are not included." % (cal.title.text) else: #Print out the title and the summary if there is one if (cal.summary is not None): print "%d) %s - Summary: %s" % (index, cal.title.text, cal.summary.text) else: print "%d) %s" % (index, cal.title.text) #Print out the authors alreadyPrintedAuthor = False for author in cal.author: if (alreadyPrintedAuthor is True): print ", %s" % (author.name.text) else: print " Author(s): %s" % (author.name.text) #Print out other information print " PUB: %s | UPD: %s | TZ: %s" % (cal.published.text, cal.updated.text, cal.timezone.value) print " CLR: %s | SEL: %s | ACS: %s" % (cal.color.value, cal.selected.value, cal.access_level.value) # Now Print out the events # print " Events:" a_link = cal.GetAlternateLink() if (a_link is not None): #print "\tA link: %s" % (a_link) # See http://jebbeich.blogspot.com/search?updated-min=2009-01-01T00%3A00%3A00-08%3A00&updated-max=2010-01-01T00%3A00%3A00-08%3A00&max-results=6 query = gdata.calendar.service.CalendarEventQuery('default', 'private', 'full') query.start_min = __first_date_to_fetch query.start_max = __last_date_to_fetch query.__dict__['feed'] = a_link.href query.max_results = 200 event_feed = self.screenlet.cal_client.CalendarQuery(query) print 'Events on calendar: %s' % (event_feed.title.text,) # print 'Event feed entry\t%s' % (event_feed.entry,) for i, an_event in zip(xrange(len(event_feed.entry)), event_feed.entry): print '\t%s. %s %s' % (i, an_event.title.text, an_event.uid.value) __start_time = 0 __end_time = 0 #for p, a_participant in zip(xrange(len(an_event.who)), an_event.who): #print '\t\t%s. %s' % (p, a_participant.email,) #print '\t\t\t%s' % (a_participant.name,) #if a_participant.attendee_status: #print '\t\t\t%s' % (a_participant.attendee_status.value,) for a_when in an_event.when: # If the event is recurring, there may be several occurances here print '\t%s - %s' % (a_when.start_time, a_when.end_time) __start_time = a_when.start_time __end_time = a_when.end_time try: if __start_time[10:11] == "T": start_eventdate = datetime.datetime(*time.strptime(__start_time[:19], "%Y-%m-%dT%H:%M:%S")[0:5]) else: start_eventdate = datetime.datetime(*time.strptime(__start_time[:10], "%Y-%m-%d")[0:5]) except Exception: start_eventdate = datetime.datetime(2010, 1, 1) print '*** START DATE MISSING!' try: if __end_time[10:11] == "T": end_eventdate = datetime.datetime(*time.strptime(__end_time[:19], "%Y-%m-%dT%H:%M:%S")[0:5]) else: end_eventdate = datetime.datetime(*time.strptime(__end_time[:10], "%Y-%m-%d")[0:5]) except Exception: end_eventdate = datetime.datetime(2010, 1, 1) print '*** END DATE MISSING!' if start_eventdate < start_datetime_fetch: continue add_this_event = True # handles modifications of events (ex. when repeated event is modified for one occurrence) if len(self.screenlet.calendarevents) > 0: index = next((i for i in xrange(len(self.screenlet.calendarevents)) if self.screenlet.calendarevents[i]["googleid"] == an_event.uid.value and self.screenlet.calendarevents[i]["start_time"] == start_eventdate), None) if index is not None: an_id_event=self.screenlet.calendarevents[index] if an_event.updated >= an_id_event["updated"]: an_id_event.update([{"googleid": an_event.uid.value, "calenderid": i, "color": cal.color.value, "title": an_event.title.text, "content": an_event.content.text, "start_time": start_eventdate, "end_time": end_eventdate, "updated": an_event.updated.text}]) print "\t\tEvent description updated" else: print "\t\tEvent skipped because a newer mod exists" add_this_event = False if add_this_event: self.screenlet.calendarevents.extend([{"googleid": an_event.uid.value, "calenderid": i, "color": cal.color.value, "title": an_event.title.text, "content": an_event.content.text, "start_time": start_eventdate, "end_time": end_eventdate, "updated": an_event.updated.text}]) print "\t\tEvent added" self.screenlet.calendarevents.sort(key=itemgetter('start_time'), reverse=False) except: traceback.print_exc() err = True finally: self.__lock.release() print "END RETRIEVE" self.dealingWithData = False gobject.idle_add(self.screenlet.on_reloaded, not err) @tdoc class GoogleCalendarScreenlet (screenlets.Screenlet): """Puts all your Google calendars on your desktop. Very customizable.""" # default meta-info for Screenlets (should be remofved and put into metainfo) __name__ = 'GoogleCalendarScreenlet' __version__ = '0.4.15+' __author__ = 'boamaod@gmail.com' __requires__ = ['python-gdata (>= 2.0.10)'] __desc__ = __doc__ # set description to docstring of class # a list of google calendar events calendarevents = [ ] # current index of the displayed documents __currentIndex = 0 # Id of the selected row __selectedRow = 0 # Are we handling a search right now? __onSearch = False # Search String __searchW = '' # Variable to keep search results __resultsCalendaritems = [ ] __events_area = None __all_area = None __events_ctx = None __events_test_ctx = None __events_buffer = None __events_test_buffer = None __events_layout = None __events_test_layout = None __text_height = 131 __customDateFormat = None # __customWeekdayFormat = None __customTimeFormat = None __notifier = None cal_client = None __lock = threading.Lock() retrieving = False date_bg_file = None full_bg_file = None events_bg_file = None bg_type = 0 reload_menu = None __updater = None connected = False connected_prev = True good_login = False __update_prev = True themes_dir = sys.path[0] + '/themes/' # editable options (options that are editable through the UI) loginCredentials = ('','') # Documents list's font color - default white # font_color =(255.0, 255.0, 255.0, 1) exportDirectory= '/' # START Copied var defs from eventCalScreenlet # internals __timeout = None __timeout_net = None __first_day = 0 __day_names = [] rgba_color = (255, 255, 255, 1) date_day_color = (255, 255, 255, 1) date_weekday_color = (255, 255, 255, 1) date_month_color = (255, 255, 255, 1) event_weekday_color = (255, 255, 255, 1) event_time_color = (255, 255, 255, 1) bg_rgba_color = (0.01, 0.01, 0.01, 0.5) todaytxt = _('Today') tomorrowtxt = _('Tomorrow') dayaftertomorrowtxt = '' themeBehind = False scaleTheme = True roundCorner = True # DIY overkill CustomDateFormat = _('%d.%m') CustomTimeFormat = _('%H:%M') CustomWeekdayFormat = _('%A') tabs = [16,55,60,99] dt_before = '\\t' dt_after = '' ind_prefix = '\\t' prefix_title = '\\t\\t' allday_prefix = '' allday_suffix = '' prefix_far_notime = '\\t' prefix_far_time = '\\t' prefix_far_title = '\\t' far_allday_prefix = '\\t' far_allday_suffix = '' ret = '\\n' # width of calendar date panel dateWidth = 130 dateHeight = 131 # width of events panel eventsWidth = 270 eventsHeight = 131 # padding for all the panels, as well as margin padding = 10 # for scrolling the event list with the mouse wheel scroll_step = 15 scroll_offset = 0 scroll_tooltip = _("Use mouse wheel to scroll up/down the event list") # settings update_interval = 10 first_weekday = '' p_layout = None day = '' showEvents = True showDate = True autoHide = False eventDaysToShow = 7 farAwayFuture = 6 # normal event text buffer txt = '' # in far away future buffer txtExtra = '' demo_number = '' int_example = 1 bool_example = True time_example = (7, 30, 0) account_example = ('','') color_example =(0.0, 0.0, 0.0, 1) text_font="Sans 9" date_big_font="Sans Bold 56" date_big_pos=0.16 date_month_year_font="Sans 10" date_month_year_pos=0.09 date_weekday_font="Sans 10" date_weekday_pos=0.75 image_example = '' file_example = '' directory_example = '' list_example = ('','') hover = False number = 0 calendar_indicator_char= "●" # to let drawing routine know if createEventList found any events or not eventsFound = False # END Copied var defs from eventCalScreenlet # constructor def __init__(self, **keyword_args): """Init""" screenlets.Screenlet.__init__(self, width=X_SIZE, height=Y_SIZE, uses_theme=True, **keyword_args) # get localized day names self.__updater = Updater(self) self.__notifier = screenlets.utils.Notifier(self) locale.setlocale(locale.LC_ALL, ''); # we convert to unicode here for the first letter extraction to work well self.__day_names = [locale.nl_langinfo(locale.DAY_1 + i).decode() for i in range(7)] self.first_weekday = self.__day_names[self.__first_day] # call super (and not show window yet) # set theme self.theme_name = "default" self.width = X_SIZE self.height = Y_SIZE ''' ----------------------------------------- Properties ----------------------------------------- ''' # add option group self.add_options_group(_('gCal essential'), _('Please fill in the gCal essential properties ...')) # TODO: add to __setattr__ which are needed # add editable option to the group # self.add_option(ColorOption('gCal','font_color', self.font_color, _('Font color'), _('Choose the font color'))) self.add_option(AccountOption(_('gCal essential'),'loginCredentials',self.loginCredentials, _('Google account'),_('Enter username and password. gCal is using system keyring encryption.'))) self.add_option(IntOption(_('gCal essential'), 'update_interval', self.update_interval, _('Update interval'), _('The interval for updating info (in minutes)'), min=1, max=120),realtime=True) self.add_option(IntOption(_('gCal essential'), 'eventDaysToShow', self.eventDaysToShow, _('Calendar length'), _('How many days to show events for'), min=0, max=60), realtime=False) self.add_option(IntOption(_('gCal essential'), 'farAwayFuture', self.farAwayFuture, _('Active interval'), _('Starting from this amount of days towards future, the event data is displayed in compressed format'), min=0, max=60), realtime=True) self.add_option(BoolOption(_('gCal essential'), 'showEvents',bool(self.showEvents), _('Show events'),_('Show the event pane')),realtime=True) self.add_option(BoolOption(_('gCal essential'), 'autoHide',bool(self.autoHide), _('Auto hide on no events'),_('Auto hide events pane on no events')),realtime=True) self.add_option(BoolOption(_('gCal essential'), 'showDate',bool(self.showDate), _('Show date'),_('Show the current date pane')),realtime=True) self.add_option(StringOption(_('gCal essential'), 'calendar_indicator_char', self.calendar_indicator_char,_('Indicator character'), _('What character to use for the coloured calendar indicators (leave empty if you don\'t want color indication!)'),),realtime=True) self.add_option(StringOption(_('gCal essential'), 'todaytxt', self.todaytxt,_('Today title'), _('Your preferred label for today\'s events section'),),realtime=True) self.add_option(StringOption(_('gCal essential'), 'tomorrowtxt', self.tomorrowtxt,_('Tomorrow title'), _('Your preferred label for tomorrows\'s events section'),),realtime=True) self.add_option(StringOption(_('gCal essential'), 'dayaftertomorrowtxt', self.dayaftertomorrowtxt,_('Day after tomorrow'), _('Your preferred label for day after tomorrow\'s events section'),),realtime=True) self.add_options_group(_('gCal window'), _('Please fill in the gCal window properties ...')) self.add_option(IntOption(_('gCal window'), 'dateWidth', self.dateWidth, _('Date panel width'), _('Date panel width'), min=130, max=2000),realtime=True) self.add_option(IntOption(_('gCal window'), 'dateHeight', self.dateHeight, _('Date panel height'), _('Date panel height'), min=131, max=3000),realtime=True) self.add_option(IntOption(_('gCal window'), 'eventsWidth', self.eventsWidth, _('Events panel width'), _('Events panel width'), min=130, max=2000),realtime=True) self.add_option(IntOption(_('gCal window'), 'eventsHeight', self.eventsHeight, _('Events panel height'), _('Events panel height'), min=131, max=3000),realtime=True) self.add_option(BoolOption(_('gCal window'), 'roundCorner',bool(self.roundCorner), _('Background round corners'),_('Draw background with round corners')),realtime=True) self.add_option(ColorOption(_('gCal window'), 'bg_rgba_color', self.bg_rgba_color, _('Background color'), _('The default color of the background (can be transparent too)')), realtime=True) self.add_option(BoolOption(_('gCal window'), 'scaleTheme',bool(self.scaleTheme), _('Scale background images'),_('Scale theme images to fit fully into the background')),realtime=True) self.add_option(BoolOption(_('gCal window'), 'themeBehind',bool(self.themeBehind), _('Theme behind background'),_('Theme behind rendered background')),realtime=True) self.add_options_group(_('gCal appearance'), _('Please fill in the gCal appearance properties ...')) self.add_option(FontOption(_('gCal appearance'), 'text_font', self.text_font, _('Event text font'), _('Font to use for event list')), realtime=True) self.add_option(ColorOption(_('gCal appearance'), 'rgba_color', self.rgba_color, _('Event text color'), _('The default color of the text (when no markup is used)')), realtime=True) self.add_option(ColorOption(_('gCal appearance'), 'event_weekday_color', self.event_weekday_color, _('Event weekday color'), _('The default color of the weekday name (transparency does not work)')), realtime=True) self.add_option(ColorOption(_('gCal appearance'), 'event_time_color', self.event_time_color, _('Event timestamp color'), _('The default color of the date/time displayed in front of events (transparency does not work)')), realtime=True) self.add_option(FontOption(_('gCal appearance'), 'date_month_year_font', self.date_month_year_font, _('Date month font'), _('Font to use to display month and year of the current date')), realtime=True) self.add_option(ColorOption(_('gCal appearance'), 'date_month_color', self.date_month_color, _('Date month color'), _('The default color for the month name text')), realtime=True) self.add_option(FloatOption(_('gCal appearance'), 'date_month_year_pos', self.date_month_year_pos, _('Date month position'), _('Position on the pane'), min=0, max=1, increment=0.01, digits=2)) self.add_option(FontOption(_('gCal appearance'), 'date_big_font', self.date_big_font, _('Date day font'), _('Font to use to display day of the current date')), realtime=True) self.add_option(ColorOption(_('gCal appearance'), 'date_day_color', self.date_day_color, _('Date day color'), _('The default color for day')), realtime=True) self.add_option(FloatOption(_('gCal appearance'), 'date_big_pos', self.date_big_pos, _('Date day position'), _('Position on the pane'), min=0, max=1, increment=0.01, digits=2)) self.add_option(FontOption(_('gCal appearance'), 'date_weekday_font', self.date_weekday_font, _('Date weekday font'), _('Font to use to display weekday of the current date')), realtime=True) self.add_option(ColorOption(_('gCal appearance'), 'date_weekday_color', self.date_weekday_color, _('Date weekday color'), _('The default color for the weekday text')), realtime=True) self.add_option(FloatOption(_('gCal appearance'), 'date_weekday_pos', self.date_weekday_pos, _('Date weekday position'), _('Position on the pane'), min=0, max=1, increment=0.01, digits=2)) self.add_options_group(_('DIY overkill'), _('You can change here some of the the strings gCal uses \nto display things. You can use Pango Markup as described \nat http://www.pygtk.org/docs/pygtk/pango-markup-language.html\n and for the date/time formatting have a look at \nhttp://docs.python.org/library/datetime.html#strftime-strptime-behavior')) self.add_option(StringOption(_('DIY overkill'), 'CustomDateFormat', self.CustomDateFormat,_('Date formatting'), _('For far away events. Use %m for month as a number, %b for month as text, %d for day. Example: %d/%m. Find more info from http://docs.python.org/library/datetime.html#strftime-strptime-behavior'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'CustomTimeFormat', self.CustomTimeFormat,_('Time formatting'), _('Use %H for hours 0-23, %I for hours 0-11, %M for minutes, %p for AM/PM indicator, if that supported by locale. Find more info from http://docs.python.org/library/datetime.html#strftime-strptime-behavior'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'CustomWeekdayFormat', self.CustomWeekdayFormat,_('Weekday formatting'), _('For day names or however you choose to custom them. Use %A for weekday name, %m for month as a number, %b for month as text, %d for day. Example: %d/%m. Find more info from http://docs.python.org/library/datetime.html#strftime-strptime-behavior'),),realtime=True) self.add_option(ListOption(_('DIY overkill'), 'tabs', self.tabs, _('Tab positions'), _('Tabulator positions')),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'dt_before', self.dt_before, _('Day prefix'), _('Before day text'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'dt_after', self.dt_after, _('Day suffix'), _('After day text'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'ind_prefix', self.ind_prefix, _('Indicator suffix'), '' ),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'prefix_title', self.prefix_title, _('Title prefix'), '' ),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'allday_prefix', self.allday_prefix, _('Allday prefix'), _('Before full day event text'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'allday_suffix', self.allday_suffix, _('Allday suffix'), _('After full day event text'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'prefix_far_notime', self.prefix_far_notime, _('Far no time prefix'), '' ),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'prefix_far_time', self.prefix_far_time, _('Far time prefix'), '' ),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'prefix_far_title', self.prefix_far_title, _('Far title prefix'), '' ),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'far_allday_prefix', self.far_allday_prefix, _('Far allday prefix'), _('Before full day event text'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'far_allday_suffix', self.far_allday_suffix, _('Far allday suffix'), _('After full day event text'),),realtime=True) self.add_option(StringOption(_('DIY overkill'), 'ret', self.ret, _('Return char'), _('Carriage return char'),),realtime=True) # scrolling is for events self.resize_on_scroll = False # this is needed only for the tooltip self.__events_area = gtk.Fixed() self.__all_area = gtk.Fixed() self.__all_area.put(self.__events_area, 0, 0) self.window.add(self.__all_area) # self.window.add(self.__events_area) # attribute-"setter", handles setting of attributes def __setattr__(self, name, value): """Set attr""" # call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!) screenlets.Screenlet.__setattr__(self, name, value) # check for this Screenlet's attributes, we are interested in: # TODO: add ALL attributes which make screenlet window to need resizing!! if name == "hide_events_panel" or name == "hide_date_panel" or name == "showDate" or name == "showEvents" or name == "autoHide" or name=="dateWidth" or name=="dateHeight" or name=="eventsWidth" or name=="eventsHeight": if self.window: self.calculateWindow() self.calculateTxtHeight() self.redraw_canvas() # TODO: add ALL attributes which make screenlet window to need redrawing!! if name=='CustomTimeFormat' or name=='CustomDateFormat' or name=='CustomWeekdayFormat' or name=='date_big_font' or name == 'date_month_year_font' or name == 'date_weekday_font' or name=='date_big_pos' or name == 'date_month_year_pos' or name == 'date_weekday_pos' or name == 'rgba_color' or name == "date_day_color" or name == "date_month_color" or name == "date_weekday_color" or name == 'bg_rgba_color' or name == "text_font" or name == "calendar_indicator_char" or name == "event_weekday_color" or name == "event_time_color" or name == "todaytxt" or name == "tomorrowtxt" or name == "dayaftertomorrowtxt" or name == 'tab' or name == 'ret' or name == 'dt_before' or name == 'dt_after' or name=="farAwayFuture" or name == 'tabs' or name.find("prefix") >= 0: if self.window: self.createEventList() self.redraw_canvas() if name == "update_interval": if value > 0: self.__dict__['update_interval'] = value if self.__timeout: gobject.source_remove(self.__timeout) self.__timeout = gobject.timeout_add(value * 60000, self.update) else: # TODO: raise exception!!! pass def get_date_info(self): """Date info""" today = datetime.datetime.now() day = today.strftime(_("%d")) month = today.month year = today.year # apply month shift # get first day of the updated month first_day = datetime.date(year, month, 1) # get the month name month_name = first_day.strftime(_("%B")) # get the day name day_name = today.strftime(_("%A")) # get the day count if month in [1, 3, 5, 7, 8, 10, 12]: days_in_month = 31 elif month != 2: days_in_month = 30 elif year % 4 == 0: days_in_month = 29 else: days_in_month = 28 # find the first day of the month start_day = (int(first_day.strftime("%u")) % 7) + 1 # return as array return [day, year, month_name, days_in_month, start_day, day_name] def update (self): """Update login and calendar data""" print "Running update" self.bg_rgba_color = self.bg_rgba_color try: if not self.checkConnected(): raise NameError('Not connected exception') if self.__timeout_net: gobject.source_remove(self.__timeout_net) if self.cal_client is None: self.loginGAccount() # this updates the calendar data, screen is refreshed in on_draw self.retrieveEventsOnAllCalendars() except Exception: if self.checkConnected(): self.connected_prev = self.connected self.connected = True if self.__timeout_net: gobject.source_remove(self.__timeout_net) self.loginGAccount() return True else: if self.connected is not self.connected_prev: self.__notifier.notify(_("Internet connection failed.")) print "Not connected to internet." self.connected_prev = self.connected if self.__timeout_net: gobject.source_remove(self.__timeout_net) self.__timeout_net = gobject.timeout_add(10000, self.update) return True # still try to force repairing connection etc # try: # self.loginGAccount() # except Exception: # print "Couldn't fix." # if self.__timeout: # gobject.source_remove(self.__timeout) if not self.__timeout: self.__timeout = gobject.timeout_add(int(self.update_interval) * 60000, self.update) return True # keep running this event def on_after_set_atribute(self,name, value): """Called after setting screenlet atributes""" if name == 'loginCredentials' or name == 'eventDaysToShow': # print "*** Running on_after_set_atribute for name: " + name if self.connected and self.loginCredentials[0] and self.loginCredentials[1] and self.loginGAccount(): if name == 'loginCredentials': self.__notifier.notify(_("Login successful.")) self.retrieveEventsOnAllCalendars() if name == 'CustomDateFormat' or name == 'CustomTimeFormat': # print "*** Running on_after_set_atribute for name: " + name # Hmmm... better check if the user entered something that won't cause the # screenlet to stop working. If so, - reset to default. try: __tmpdate = datetime.now() print __tmpdate.strftime(value) except Exception: if name == 'CustomDateFormat': CustomDateFormat = '' elif name == 'CustomTimeFormat': CustomTimeFormat = '' elif name == 'CustomWeekdayFormat': CustomWeekdayFormat = '' print 'Bad custom ' + name + ' rules entered' self.redraw_canvas() pass def menuitem_callback(self, widget, id): """Deal with menu choices using widget object????""" screenlets.Screenlet.menuitem_callback(self, widget, id) def on_before_set_atribute(self,name, value): """Called before setting screenlet atributes""" pass def on_create_drag_icon (self): """Called when the screenlet's drag-icon is created. You can supply your own icon and mask by returning them as a 2-tuple.""" return (None, None) def on_composite_changed(self): """Called when composite state has changed""" pass def on_drag_begin (self, drag_context): """Called when the Screenlet gets dragged.""" pass def on_drag_enter (self, drag_context, x, y, timestamp): """Called when something gets dragged into the Screenlets area.""" pass def on_drag_leave (self, drag_context, timestamp): """Called when something gets dragged out of the Screenlets area.""" pass def on_drop (self, x, y, sel_data, timestamp): """Called when a selection is dropped on this Screenlet.""" return False def on_focus (self, event): """Called when the Screenlet's window receives focus.""" self.__has_focus = True pass def on_hide (self): """Called when the Screenlet gets hidden.""" pass def on_init (self): """Called when the Screenlet's options have been applied and the screenlet finished its initialization. If you want to have your Screenlet do things on startup you should use this handler.""" ''' ----------------------------------------- Menu items ----------------------------------------- ''' print '*** Running on_init' self.add_menuitem("hide_events_panel", _("Toggle hide/view calendar events")) self.add_menuitem("hide_date_panel", _("Toggle hide/view current date")) self.reload_menu = self.add_menuitem("update", _("Update events now")) # self.add_menuitem("RefreshCalendar", "Refresh calendar") # self.add_menuitem("Reconnect", "Reconnect to Google Calendar") self.add_default_menuitems() print '\033[0;36mGoogleCalendarScreenlet started.\033[0m' # this is the most stupidest thing to do, but it won't work ok otherwise self.bg_rgba_color = self.bg_rgba_color # self.bg_rgba_color = [0,0,0,0.5] self.calculateWindow() self.redraw_canvas() # if not self.checkConnected(): # # ADD a 10 seconds (10000) TIMER # # to check the internet connection # if(self.__timer_net): # gobject.source_remove(self.__timer_net) # self.__timeout_net = gobject.timeout_add(10000, self.update) # else: # self.connected = True self.update() if not self.__timeout: self.__timeout = gobject.timeout_add(int(self.update_interval) * 60000, self.update) # print self.width, ", ", self.height def on_key_down(self, keycode, keyvalue, event): """Called when a keypress-event occured in Screenlet's window.""" key = gtk.gdk.keyval_name(event.keyval) # self.redraw_canvas() pass def on_load_theme (self): """Called when the theme is reloaded (after loading, before redraw).""" print self.themes_dir + self.theme_name # theme file name first parts self.full_bg_file = self.themes_dir + self.theme_name + '/calendar1' self.date_bg_file = self.themes_dir + self.theme_name + '/calendar' self.events_bg_file = self.themes_dir + self.theme_name + '/calendar2' # check the contents if os.path.isfile(self.full_bg_file + ".svg"): self.full_bg_file = self.full_bg_file + ".svg" elif os.path.isfile(self.full_bg_file + ".png"): self.full_bg_file = self.full_bg_file + ".png" else: self.full_bg_file = None if os.path.isfile(self.date_bg_file + ".svg"): self.date_bg_file = self.date_bg_file + ".svg" elif os.path.isfile(self.date_bg_file + ".png"): self.date_bg_file = self.date_bg_file + ".png" else: self.date_bg_file = None if os.path.isfile(self.events_bg_file + ".svg"): self.events_bg_file = self.events_bg_file + ".svg" elif os.path.isfile(self.events_bg_file + ".png"): self.events_bg_file = self.events_bg_file + ".png" else: self.events_bg_file = None print "THEME FILES AVAILABLE" print "Full", self.full_bg_file print "Date", self.date_bg_file print "Events", self.events_bg_file self.findOutThemingOptions() def on_menuitem_select (self, id): """Called when a menuitem is selected.""" if id == "hide_events_panel": self.showEvents = not self.showEvents if id == "hide_date_panel": self.showDate = not self.showDate if id == "hide_events_panel" or id == "hide_date_panel": self.calculateWindow() self.redraw_canvas() if id=="update": self.update() # if id == "update": # self.update() # if id == "RefreshCalendar": # self.retrieveEventsOnAllCalendars() # self.redraw_canvas() # elif id =="Reconnect": # print 'trying to log in' #if successful # if self.connected and self.loginGAccount(): # self.retrieveEventsOnAllCalendars() # self.redraw_canvas() # pass def on_mouse_down (self, event): """Called when a buttonpress-event occured in Screenlet's window. Returning True causes the event to be not further propagated.""" def on_mouse_enter (self, event): """Called when the mouse enters the Screenlet's window.""" self.hover = True def on_mouse_leave (self, event): """Called when the mouse leaves the Screenlet's window.""" self.hover = False def on_mouse_move(self, event): """Called when the mouse moves in the Screenlet's window.""" pass def on_mouse_up (self, event): """Called when a buttonrelease-event occured in Screenlet's window. Returning True causes the event to be not further propagated.""" return False def on_quit (self): """Callback for handling destroy-event. Perform your cleanup here!""" if self.__timeout_net: gobject.source_remove(self.__timeout_net) if self.__timeout: gobject.source_remove(self.__timeout) return True def on_realize (self): """"Callback for handling the realize-event.""" def on_scale (self): """Called when Screenlet.scale is changed.""" pass def on_scroll_up (self): """Called when mousewheel is scrolled up (button4).""" self.scroll_offset -= self.scroll_step if self.scroll_offset < 0 : self.scroll_offset = 0 self.redraw_canvas() return True def on_scroll_down (self): """Called when mousewheel is scrolled down (button5).""" self.scroll_offset += self.scroll_step if self.scroll_offset > self.__text_height - self.eventsHeight: self.scroll_offset = self.__text_height - self.eventsHeight self.redraw_canvas() return True def on_show (self): """Called when the Screenlet gets shown after being hidden.""" pass def on_switch_widget_state (self, state): """Called when the Screenlet enters/leaves "Widget"-state.""" pass def on_unfocus (self, event): """Called when the Screenlet's window loses focus.""" self.__has_focus = False pass def on_reloaded (self, result): """Called by updater""" # register that everything went fine for the next time if result == True: if not self.connected_prev: if self.__timeout_net: gobject.source_remove(self.__timeout_net) self.__notifier.notify(_("Connected to internet and updating again.")) self.connected = True self.connected_prev = self.connected self.__update_prev = True else: if self.__update_prev and self.good_login: self.__notifier.notify(_("Update failed for some unknown reason.")) self.__update_prev = False print "Update failed for some unknown reason." self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) self.reload_menu.set_sensitive(True) if result == True: self.createEventList() self.redraw_canvas() def on_draw(self, ctx): """on_draw""" if not self.window: return if not self.has_started: return # print '*** Running on_draw' # get data date = self.get_date_info() # [day, year, month_name, days_in_month, start_day] # draw bg (if theme available) ctx.set_operator(cairo.OPERATOR_OVER) # set size ctx.scale(self.scale, self.scale) if self.themeBehind: self.drawTheme(ctx) # print self.bg_rgba_color # draw the normal background # a = self.bg_rgba_color[0] # b = self.bg_rgba_color[1] # c = self.bg_rgba_color[2] # d = self.bg_rgba_color[3] # print a,b,c,d # ctx.set_source_rgba(0,0,0.5,0.5) # ctx.set_source_rgba(a,b,c,d) # ctx.set_source_rgba(1,2,3,4) ctx.set_source_rgba(self.bg_rgba_color[0], self.bg_rgba_color[1], self.bg_rgba_color[2], self.bg_rgba_color[3]) # ctx.set_source_rgba(0.3,0.5,0.5,0.5) if self.roundCorner: self.draw_rounded_rectangle(ctx,0,0, self.padding,self.width, self.height) else: self.draw_rectangle(ctx,0,0, self.width, self.height) if not self.themeBehind: self.drawTheme(ctx) if self.showEvents: # if the credentials haven't been set if self.loginCredentials[0] == '': ctx.set_source_rgba(self.rgba_color[0], self.rgba_color[1], self.rgba_color[2], self.rgba_color[3]) self.draw_text(ctx, _("\nCan't display events, because no login credentials are provided. Please provide the credentials using the configuration dialog. Your credentials are stored safely into system keyring and reloaded from keyring every time the screenlet is started."), self.xpos(), self.padding , self.text_font , 9, self.eventsWidth, self.width,pango.ALIGN_LEFT) elif self.cal_client is None and not self.connected: ctx.set_source_rgba(self.rgba_color[0], self.rgba_color[1], self.rgba_color[2], self.rgba_color[3]) self.draw_text(ctx, _("\nWaiting for the connection..."), self.xpos(), self.padding , self.text_font , 9, self.eventsWidth, self.width,pango.ALIGN_LEFT) elif self.eventsFound: self. drawEvents(ctx); if self.showDate: self.drawDate(ctx, date) if not self.showEvents and not self.showDate: self.theme.draw_scaled_image(ctx, 0, 0, sys.path[0] + '/icon.svg', self.width, self.height) self.window.resize(int(self.width * self.scale), int(self.height * self.scale)) ctx.scale(self.scale, self.scale) ctx.stroke () def drawTheme(self, ctx): """Draws the theme pictures""" if not self.theme: return if self.bg_type == 1: # full if self.scaleTheme == True: self.theme.draw_scaled_image(ctx, 0, 0, self.full_bg_file, self.width, self.height) else: self.theme.render(ctx, 'calendar1') if self.bg_type == 2 or self.bg_type == 4: # date if self.scaleTheme == True: self.theme.draw_scaled_image(ctx, 0, 0, self.date_bg_file, self.dateWidth + self.padding*2, self.dateHeight + self.padding*2) else: self.theme.render(ctx, 'calendar') if self.bg_type == 3 or self.bg_type == 4: # events if self.scaleTheme == True: self.theme.draw_scaled_image(ctx, self.xpos() - self.padding, 0, self.events_bg_file, self.eventsWidth + self.padding*2, self.eventsHeight + self.padding*2) else: self.theme.draw_image(ctx, self.xpos() - self.padding, 0, self.events_bg_file) def xpos(self): """returns presumable x position of the events pane""" if self.showDate: xpos = self.dateWidth + self.padding*3 else: xpos = self.padding return xpos def calculateWindow(self): """calculates window size from the elements present, sets tooltip position, updates theming variables""" # print "*** Running calculateWindow" h=0 w=0 if (self.showEvents and not self.autoHide) or (self.showEvents and self.autoHide and self.eventsFound): h = max(self.eventsHeight, h) w += self.eventsWidth if self.showDate: h = max(self.dateHeight, h) w += self.dateWidth if w == 0 or h == 0: w = self.dateHeight h = self.dateWidth if self.showDate and ((self.showEvents and not self.autoHide) or (self.showEvents and self.autoHide and self.eventsFound)): w += self.padding*2 # line between # margin=padding w += self.padding*2 h += self.padding*2 self.height= h self.width = w self.findOutThemingOptions() # events pane tooltip area if (self.showEvents and not self.autoHide) or (self.showEvents and self.autoHide and self.eventsFound): if self.__events_area: self.__events_area.set_size_request(int(self.eventsWidth * self.scale), int(self.eventsHeight * self.scale)) if self.__all_area: self.__all_area.move(self.__events_area, int(self.xpos() * self.scale), int(self.padding * self.scale)) self.__events_area.set_tooltip_text(self.scroll_tooltip) self.window.show_all() else: self.__events_area.set_tooltip_text("") def findOutThemingOptions(self): """Detects which theming option should be used for current pane configuration bg_type: 0 - none, 1 - full, 2 - date, 3 - events, 4 - both""" self.bg_type = 0 # detect which kind of theming is recommended if self.theme: if self.showDate and (self.showEvents and not self.autoHide) or (self.showEvents and self.autoHide and self.eventsFound): if self.full_bg_file is not None: # one full image self.bg_type = 1 if self.bg_type != 1: # try both other parts if self.date_bg_file is not None: self.bg_type = 2 if self.events_bg_file is not None: if self.bg_type == 2: self.bg_type = 4 else: self.bg_type = 3 elif self.showDate: if self.date_bg_file is not None: self.bg_type = 2 elif (self.showEvents and not self.autoHide) or (self.showEvents and self.autoHide and self.eventsFound): if self.events_bg_file is not None: self.bg_type = 3 sys.exit(0) def createEventList(self): """create the list into self.txt ja self.txtExtra, set self.eventsFound""" # The calentries list has the following named keys: googleid, calenderid, color, title, # content, start_time, end_time, updated if not self.showEvents: return IND_PREFIX = self.ind_prefix.decode("string_escape") PREFIX_TITLE = self.prefix_title.decode("string_escape") PREFIX_FAR_TIME = self.prefix_far_time.decode("string_escape") PREFIX_FAR_NOTIME = self.prefix_far_notime.decode("string_escape") PREFIX_FAR_TITLE = self.prefix_far_title.decode("string_escape") ALLDAY_PREFIX = self.allday_prefix.decode("string_escape") FAR_ALLDAY_PREFIX = self.far_allday_prefix.decode("string_escape") ALLDAY_SUFFIX = self.allday_suffix.decode("string_escape") FAR_ALLDAY_SUFFIX = self.far_allday_suffix.decode("string_escape") RET = self.ret.decode("string_escape") DT_BEFORE = self.dt_before.decode("string_escape") DT_AFTER = self.dt_after.decode("string_escape") # for autohide prev_ev_f=self.eventsFound # normal event text self.txt = '' # in far away future self.txtExtra = '' daycount=0 runningDate = "" calentries = self.calendarevents # get data date = self.get_date_info() # [day, year, month_name, days_in_month, start_day] if len(calentries) != 0: today=datetime.date.today() for calentry in calentries: if calentry['title'] == None: # had this problem, just added this check here! continue startDate = datetime.date.fromordinal(calentry['start_time'].toordinal()) strStartTime = str(calentry['start_time'])[11:16] strEndTime = str(calentry['end_time'])[11:16] alldayevent = False if strStartTime == '00:00' and strEndTime == '00:00': alldayevent = True # strStartTime = strEndTime = TAB # print 'drawCalEntryList: ' + str(startDate) + ' ' + strStartTime + TAB +' ' + calentry['title'] # print str(today) + " ---" + str(startDate) if(len(self.CustomTimeFormat) > 0 and not alldayevent): # print "==================================>>>>" # print self.CustomTimeFormat + ": " + strStartTime + " -> " + time.strftime(self.CustomTimeFormat, time.strptime(strStartTime, "%H:%M")) # print strStartTime # ts = time.strptime(strStartTime, "%H:%M") # print self.CustomTimeFormat # print time.strftime(self.CustomTimeFormat, ts) # self.__customTimeFormat = re.sub(r_("\b0"),"",time.strftime(self.CustomTimeFormat, time.strptime(strStartTime, "%H:%M"))) self.__customTimeFormat = time.strftime(self.CustomTimeFormat, time.strptime(strStartTime, _("%H:%M"))) else: self.__customTimeFormat = strStartTime = strEndTime = "" # this is not really normal way to convert different color representations, but does the job quite universally if isinstance(self.event_weekday_color[0], int): dayTxtColor = "" else: dayTxtColor = "" if isinstance(self.event_time_color[0], int): dayTimeColor = "" else: dayTimeColor = "" if runningDate == startDate: daytxt = "" elif today == startDate and self.todaytxt.strip() != "": daytxt = dayTxtColor + self.todaytxt.strip() + "" runningDate=startDate elif today == startDate - datetime.timedelta(days=1) and self.tomorrowtxt.strip() != "": daytxt = dayTxtColor + self.tomorrowtxt.strip() + "" runningDate=startDate elif today == startDate - datetime.timedelta(days=2) and self.dayaftertomorrowtxt.strip() != "": daytxt = dayTxtColor + self.dayaftertomorrowtxt.strip() + "" runningDate=startDate else: delta = startDate - today daytxt = dayTxtColor + (today + datetime.timedelta(days=delta.days)).strftime(self.CustomWeekdayFormat).strip() + "" runningDate=startDate daycount += 1 # choose whether to display in compressed or normal calendar mode if startDate > today + datetime.timedelta(days=self.farAwayFuture): # far away display if(len(self.CustomDateFormat) > 0): self.__customDateFormat = re.sub(r"\b0","",startDate.strftime(self.CustomDateFormat)) else: self.__customDateFormat = str(startDate) # TODO: this does not work since some widths of characters are variable!!! #__customDateFormat = __customDateFormat # Pad string with spaces at the end self.txtExtra += "" + self.calendar_indicator_char + "" + IND_PREFIX if self.__customTimeFormat.strip()=="": add_time = PREFIX_FAR_NOTIME else: add_time = PREFIX_FAR_TIME + self.__customTimeFormat if alldayevent: titletodisplay = FAR_ALLDAY_PREFIX +calentry['title'] + FAR_ALLDAY_SUFFIX else: titletodisplay = PREFIX_FAR_TITLE + calentry['title'] self.txtExtra += dayTimeColor + self.__customDateFormat + add_time + '' + titletodisplay + RET else: # normal display if daytxt: self.txt += DT_BEFORE+ daytxt + DT_AFTER + RET self.txt += "" + self.calendar_indicator_char + "" + IND_PREFIX if alldayevent: titletodisplay = ALLDAY_PREFIX + calentry['title'] + ALLDAY_SUFFIX else: titletodisplay = PREFIX_TITLE + calentry['title'] self.txt += dayTimeColor + self.__customTimeFormat.strip() + '' + titletodisplay + RET if self.txt == '' and self.txtExtra == '': print 'no events found' self.eventsFound = False else: self.eventsFound = True if self.autoHide and prev_ev_f != self.eventsFound: self.calculateWindow() self.__text_height = self.calculateTxtHeight() # print self.txt + RET + self.txtExtra # TODO: should return the height of events list text (self. def calculateTxtHeight(self): """should return the height of events list text""" # print "*** Running calculateTxtHeight" if not self.window.window: return RET = self.ret.decode("string_escape") if self.__events_test_buffer == None: self.__events_test_buffer = gtk.gdk.Pixmap(self.window.window, self.eventsWidth, 5000, -1) buffer = self.__events_test_buffer if self.__events_test_ctx == None: text_ctx = __events_test_ctx = buffer.cairo_create() text_ctx.rectangle(0,0,self.eventsWidth,5000) text_ctx.clip() text_ctx.set_operator(cairo.OPERATOR_OVER) else: text_ctx = __events_test_ctx if self.__events_test_layout == None: p_layout = self.__events_test_layout = text_ctx.create_layout() else: text_ctx.update_layout(self.__events_test_layout) p_layout = self.__events_test_layout text_ctx.set_source_rgba(self.rgba_color[0], self.rgba_color[1], self.rgba_color[2], self.rgba_color[3]) self.draw_text(text_ctx, self.txt + RET + self.txtExtra, 0, 0, self.text_font , 9, self.eventsWidth, pango.ALIGN_LEFT, ellipsize=pango.ELLIPSIZE_NONE, tabs = self.tabs) extents, lextents = self.p_layout.get_pixel_extents() return extents[3] def on_draw_shape (self, ctx): """on draw shape""" self.on_draw(ctx) def drawEvents (self, ctx): """Draws the event list""" # if not self.window.window: # return RET = self.ret.decode("string_escape") # TODO: i believe it should create new objects only when it's resized!!!!!!!!!!!!! # if self.__events_buffer == None: self.__events_buffer = gtk.gdk.Pixmap(self.window.window, self.eventsWidth, self.__text_height, -1) buffer = self.__events_buffer # if self.__events_ctx == None: text_ctx = __events_ctx = buffer.cairo_create() text_ctx.rectangle(0,0,self.eventsWidth, self.__text_height) text_ctx.clip() text_ctx.set_operator(cairo.OPERATOR_OVER) # else: # text_ctx = __events_ctx self.clear_cairo_context(text_ctx) # if self.__events_layout == None: # p_layout = self.__events_layout = text_ctx.create_layout() # else: # text_ctx.update_layout(self.__events_layout) # p_layout = self.__events_layout text_ctx.set_source_rgba(self.rgba_color[0], self.rgba_color[1], self.rgba_color[2], self.rgba_color[3]) self.draw_text(text_ctx, self.txt + RET + self.txtExtra, 0, 0, self.text_font , 9, self.eventsWidth, pango.ALIGN_LEFT, ellipsize=pango.ELLIPSIZE_NONE, tabs = self.tabs) ctx.save() ctx.set_operator(cairo.OPERATOR_OVER) ctx.set_source_pixmap(buffer, self.xpos(), self.padding -self.scroll_offset) ctx.rectangle(self.xpos(),self.padding, self.eventsWidth, self.eventsHeight) ctx.clip() ctx.paint() ctx.restore() def drawDate (self, ctx, date): """Draws the date""" ctx.set_source_rgba(self.date_month_color[0], self.date_month_color[1], self.date_month_color[2], self.date_month_color[3]) self.draw_text(ctx, str(date[2]) + ' ' + str(date[1]), self.padding, self.padding + self.dateHeight*self.date_month_year_pos, self.date_month_year_font, 10, self.dateWidth,pango.ALIGN_CENTER) ctx.set_source_rgba(self.date_day_color[0], self.date_day_color[1], self.date_day_color[2], self.date_day_color[3]) self.draw_text(ctx, str(date[0]), self.padding, self.padding + self.dateHeight*self.date_big_pos, self.date_big_font, 54, self.dateWidth,pango.ALIGN_CENTER) ctx.set_source_rgba(self.date_weekday_color[0], self.date_weekday_color[1], self.date_weekday_color[2], self.date_weekday_color[3]) self.draw_text(ctx, str(date[5]), self.padding, self.padding + self.dateHeight*self.date_weekday_pos, self.date_weekday_font , 10, self.dateWidth ,pango.ALIGN_CENTER) def date_internet(date): d = date.strftime('%Y-%m-%dT%H:%M:%S%z') return d[:-2] + ':' + d[-2:] def draw_text(self, ctx, text, x, y, font, size, width, allignment=pango.ALIGN_LEFT,alignment=None,justify = False,weight = 0, ellipsize = pango.ELLIPSIZE_NONE, tabs= []): """Draws text""" ctx.save() ctx.translate(x, y) if self.p_layout == None : self.p_layout = ctx.create_layout() else: ctx.update_layout(self.p_layout) self.p_fdesc = pango.FontDescription(font) # self.p_fdesc.set_family_static(font) # self.p_fdesc.set_size(size * pango.SCALE) # self.p_fdesc.set_weight(weight) self.p_layout.set_font_description(self.p_fdesc) self.p_layout.set_width(width * pango.SCALE) self.p_layout.set_alignment(allignment) if alignment != None:self.p_layout.set_alignment(alignment) self.p_layout.set_justify(justify) self.p_layout.set_ellipsize(ellipsize) tabarray = self.p_layout.get_tabs() if tabarray is None: tabarray = pango.TabArray(len(tabs), True) if tabarray.get_size() < len(tabs): tabarray.resize(len(tabs)) for i in range(0, len(tabs)): tabarray.set_tab(i, pango.TAB_LEFT, int(tabs[i])) # print i, int(tabs[i]) self.p_layout.set_tabs(tabarray) self.p_layout.set_markup(text) # print text ctx.show_layout(self.p_layout) ctx.restore() def retrieveEventsOnAllCalendars(self): # print "Üritan uuendada... ?" self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) self.reload_menu.set_sensitive(False) self.__updater.run() def checkConnected(self): """Check the internet connection""" print "Checking the Internet connection" try: # Check the connection by opening a socket to a URL connection = urllib.urlopen('http://www.google.com/robots.txt') # Connected successfully so close the socket connection.close() self.connected = True return True except Exception: # We are not connected self.connected = False return False def loginGAccount(self): """Logs into Google account""" if self.connected == True: try: self.cal_client = gdata.calendar.service.CalendarService() self.cal_client.email = self.loginCredentials[0] self.cal_client.password = self.loginCredentials[1] self.cal_client.source = 'gCal_Screenlet-' + self.__version__ self.cal_client.ProgrammaticLogin() print 'Valid Programmatic login' self.good_login = True return True except Exception: self.good_login = False if len(self.loginCredentials[0]) > 0: self.__notifier.notify(_("Invalid login, check username and password.")) return False # If the program is run directly or passed as an argument to the python # interpreter then create a Screenlet instance and show it if __name__ == "__main__": """Starts the screenlet""" # create new session import screenlets.session screenlets.session.create_session(GoogleCalendarScreenlet, threading=True)