#!/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)