def add(events): """ Add Event to events in google calendar :param events: Events object :return: """ calendar = GoogleCalendar() calendar.add_events(events)
def aggregate_markdown(): markdown = "" gc = GoogleCalendar() markdown += gc.get_events() tt = TrelloTasks() markdown += tt.get_cards('tasks', 'Doing') markdown += tt.get_cards('valencia','matt') now = datetime.datetime.now() update_str = datetime.datetime.strftime(now,'### Updated %d/%m at %H:%M') markdown += update_str return markdown
def test_calc_dates(self): print('test calc_dates') gc = GoogleCalendar() gcdb = GoogleCloudDb() utility = Utility(gcdb, None) bcs = BorrowConsoleState(utility, gc) bcs.calc_dates()
def handle(self, bot, update): if not super().handle(bot, update): return False args = self.get_args(update) (event_datetime, remaining_args) = self._parse_datetime_future(args) if event_datetime is None: bot.sendMessage(update.message.chat_id, text="Datum unverständlich :(") return event_name = remaining_args.strip() if event_name == '': bot.sendMessage(update.message.chat_id, text='Das Event braucht noch einen Namen') return if type(event_datetime) is datetime.date: new_event = self.calendar.add_date_event(event_datetime, event_name) else: new_event = self.calendar.add_datetime_event( event_datetime, datetime.timedelta(hours=2), event_name) events = self.calendar.get_events() new_event['start'] = GoogleCalendar.event_time_to_datetime( new_event['start']) bot.sendMessage(update.message.chat.id, text=self.format_events_listing(events, new_event), parse_mode=telegram.ParseMode.MARKDOWN) return True
def EventList(params): ''' Returns a list of events ''' data = {} data["text"] = [] cal = GoogleCalendar() ret = cal.events_list() if not ret: print('No upcoming events found.') for event in ret: start = event['start'].get('dateTime', event['start'].get('date')) data["text"].append(start + " - " + event['summary']) return data
def __init__(self, geocoder): self.local_time = LocalTime(geocoder) self.sun = Sun(geocoder) self.artwork = Artwork() self.city = City(geocoder) self.commute = Commute(geocoder) self.calendar = GoogleCalendar(geocoder) self.everyone = Everyone(geocoder)
def main(): setup_logging() global config config = read_config('config.ini') calendar = GoogleCalendar(config['CalendarClientSecretFile'], config['CalendarID']) setup_telegram(calendar)
def test_borrow_again(self): print('test borrow_again') gc = GoogleCalendar() gcdb = GoogleCloudDb() utility = Utility(gcdb, None) bcs = BorrowConsoleState(utility, gc) print('Assert if TRUE') self.assertTrue(bcs.borrow_again()) print('Assert if FALSE') self.assertFalse(bcs.borrow_again())
def EventCreate(params): ''' Creates an event ''' data = {} event = {} missing_params = [] ### Check mandatory parameters event["start"] = {} if "date" in params: event["start"]["dateTime"] = params["date"] else: missing_params.append("start date") event["end"] = {} if "date_end" in params: event["end"]["dateTime"] = params["date_end"] elif "duration" in params: event["end"]["dateTime"] = params["date"] # TODO: Function that computes the end else: missing_params.append("end date") ### Check if missing fields if len(missing_params) > 0: data["text"] = ["The following field(s) are missing:"] data["text"] = data["text"] + missing_params return data ### Check non-mandatory parameters if "label" in params: event["summary"] = params["label"] if "location" in params: event["location"] = params["location"] ### Call API function cal = GoogleCalendar() ret = cal.events_insert(event) print(ret) data["text"] = ["Done"] return data
def test_input(self): print('test input') list = [] gc = GoogleCalendar() gcdb = GoogleCloudDb() utility = Utility(gcdb, None) book = Book(1, 'title', 'author', '12/09/99') list.append(book) utility.add_cur_results(list) bcs = BorrowConsoleState(utility, gc) self.assertEqual(bcs.input().book_id, 1)
def test_handle_input(self): print('test handle input') list = [] gc = GoogleCalendar() gcdb = GoogleCloudDb() utility = Utility(gcdb, None) book = Book(1, 'title', 'author', '12/09/99') list.append(book) utility.add_cur_results(list) utility.user = MasterUser('username', 'firstname', 'lastname', 1) bcs = BorrowConsoleState(utility, gc) bcs.handle_input(book, utility)
def __init__(self, geocoder): """Schedule constructor. Args: geocoder (geocoder.Geocoder): Used to localize user specified locations """ self._local_time = LocalTime(geocoder) self._sun = Sun(geocoder) self._artwork = Artwork() self._city = City(geocoder) self._commute = Commute(geocoder) self._calendar = GoogleCalendar(geocoder) self._everyone = Everyone(geocoder)
def EventDelete(params): ''' Deletes an event ''' # TODO: We need a way to delete from something else than an id. More # generally speaking, we need to be able to search for a en event that # matches a description, retrieves its ID and send it to depete (or update) data = {} event = {} ### Check parameters if "id" in params: event_id = params["id"] else: data["text"] = ["Field \"id\" is missing"] return data ### Call API function cal = GoogleCalendar() ret = cal.events_delete(event_id) data["text"] = ["Delete done"] return data
def test_display(self): print('test you must search first display') gc = GoogleCalendar() gcdb = GoogleCloudDb() utility = Utility(gcdb, None) bcs = BorrowConsoleState(utility, gc) bcs.display() # Test mocks a prior search result to test the display response print('testing with search first display') list = [] book = Book(1, 'title', 'author', '12/09/99') list.append(book) utility.add_cur_results(list) bcs2 = BorrowConsoleState(utility, gc) bcs2.display()
def update_calendar_one_user(person_id, users, http): # Register the user or update credentials locations = users.get_locations(person_id) if len(locations) < 1: return location = locations[0] # now actually post the weather report report = WeatherReport(location) credentials = users.get_credentials(person_id) credentials.refresh(http) google_calendar = GoogleCalendar(credentials, http) google_calendar.clear_event(datetime.utcnow()) for day_report in report.get_days(): google_calendar.set_daily_report(day_report.date, day_report.brief_summary, day_report.full_summary) users.update_job(person_id)
)""" records = self.execute_return(query) return records if __name__ == "__main__": # Drop schema first connector = SQLDatabase.connect(host, user, password) cursor = connector.cursor() query = f"drop database if exists {schema}" cursor.execute(query) connector.commit() connector.close() # # Drop all events calendar = GoogleCalendar() calendar.cancel_all_events() # # # # Define the Database login_db = LoginDatabase() print(login_db.add_login("*****@*****.**", "112358", "user")) print(login_db.add_login("hoang", "159753", "engineer")) print(login_db.add_login("hoangesoftblog", "1", "manager")) print(login_db.add_login("hello", "123456", "admin")) print(login_db.add_login("temp1", "12", "user")) print(login_db.add_login("temp", "1", "user")) print(login_db.change_password(3, "1010101")) print(login_db.delete_login(5)) print(login_db.get_all_login()) print(login_db.find_login("hello", "123456"))
def startCalendar(self): calendar = GoogleCalendar()
def main(event, context): try: time_min, time_max, check_time_from = get_time_interval() google = GoogleCalendar() kintone = KintoneCalendarCall() polly = PollyMp3() twilio = TwilioCalendar() regist_records = kintone.get_regist() logger.info(regist_records) for regist_record in regist_records: logger.info(regist_record) calendar_id = regist_record['calendar_id']['value'] schedule_items = google.get_schedule(calendar_id, time_min, time_max) logger.info(schedule_items) polly_text = '' for schedule_item in schedule_items: if 'description' in schedule_item: description = schedule_item['description'] if 'call' in description: start_time = None end_time = None summary = None location = None check_time_to = '' check_time_dummy = '' if 'start' in schedule_item: start_time, check_time_to = generate_time_to_str( schedule_item['start']['dateTime']) if 'end' in schedule_item: end_time, check_time_dummy = generate_time_to_str( schedule_item['end']['dateTime']) if 'summary' in schedule_item: summary = schedule_item['summary'] if 'location' in schedule_item: location = schedule_item['location'] if check_time_from == check_time_to: polly_text += generate_polly_text( start_time, end_time, summary, location) if len(polly_text) > 0: tel_number = regist_record['tel_number']['value'].replace( '-', '') if tel_number[0:1] == '0': tel_number = '+81' + tel_number[1:len(tel_number)] logger.info(tel_number) file_name = generate_file_name(calendar_id) mp3_url = polly.set_mp3(file_name, polly_text) logger.info(mp3_url) twiml_str = twilio.get_twiml(mp3_url) logger.info(twiml_str) twiml_url = polly.set_twiml(file_name, twiml_str) logger.info(twiml_url) call_sid = twilio.make_call(tel_number, twiml_url) logger.info(call_sid) except Exception as e: logger.error(traceback.format_exc(sys.exc_info()[2]))
def test_event_calendars(): calendar = GoogleCalendar() calendar.get_events() assert 'Test 1' in calendar.event_list
def test_list_calendars(): calendar = GoogleCalendar() calendar.get_calendars() calendar_summary = [x['summary'] for x in calendar.calendar_list] assert 'Testing' in calendar_summary
def main(): global cal, debug_mode, display_meeting_summary, particle, use_remote_notify # Logging # Setup the basic console logger format_str = '%(asctime)s %(levelname)s %(message)s' date_format = '%Y-%m-%d %H:%M:%S' logging.basicConfig(format=format_str, level=logging.INFO, datefmt=date_format) logger = logging.getLogger() # Add a file handler as well; roll at midnight and keep 7 copies file_handler = TimedRotatingFileHandler("remind_log", when="midnight", backupCount=6) log_formatter = logging.Formatter(format_str, datefmt=date_format) file_handler.setFormatter(log_formatter) # file log always gets debug; console log level set in the config file_handler.setLevel(logging.DEBUG) logger.addHandler(file_handler) # tell the user what we're doing... print('\n') print(HASHES) print(HASH, 'Pi Remind HD Notify ', HASH) print(HASH, 'By John M. Wargo (https://johnwargo.com) ', HASH) print(HASHES) print('From: ' + PROJECT_URL + '\n') settings = Settings.get_instance() settings.validate_config_options() debug_mode = settings.get_debug_mode() if debug_mode: logging.info('Remind: Enabling debug mode') logger.setLevel(logging.DEBUG) display_meeting_summary = settings.get_display_meeting_summary() use_remote_notify = settings.get_use_remote_notify() if use_remote_notify: logging.info('Remind: Remote Notify Enabled') access_token = settings.get_access_token() device_id = settings.get_device_id() # Check to see if the string values we need are populated if len(access_token) < 1 or len(device_id) < 1: logging.error('One or more values are missing from the project configuration file') logging.error(CONFIG_ERROR_STR) sys.exit(0) logging.debug('Remind: Creating Particle object') particle = ParticleCloud(access_token, device_id) logging.info('Remind: Resetting Remote Notify status') particle.set_status(Status.FREE.value) time.sleep(1) particle.set_status(Status.OFF.value) # is the reboot counter in play? use_reboot_counter = settings.get_use_reboot_counter() if use_reboot_counter: # then get the reboot counter limit reboot_counter_limit = settings.get_reboot_counter_limit() # and tell the user the feature is enabled logging.info('Remind: Reboot enabled ({} retries)'.format(reboot_counter_limit)) logging.info('Remind: Initializing Google Calendar interface') try: cal = GoogleCalendar() # Set the timeout for the rest of the Google API calls. # need this at its default during the registration process. socket.setdefaulttimeout(5) # seconds except Exception as e: logging.error('Remind: Unable to initialize Google Calendar API') logging.error('Exception type: {}'.format(type(e))) logging.error('Error: {}'.format(sys.exc_info()[0])) unicorn.set_all(unicorn.FAILURE_COLOR) time.sleep(5) unicorn.off() sys.exit(0) logging.info('Remind: Application initialized') # flash some random LEDs just for fun... unicorn.flash_random(5, 0.5) # blink all the LEDs GREEN to let the user know the hardware is working unicorn.flash_all(3, 0.10, unicorn.GREEN) # get to work processing_loop()
class MainWindow(Gtk.Window): def __init__(self): self.row = 0 self.event_container = None self.prefs_window = prefs.PrefsWindow() # Initialize the taskbar icon self.appindicator = AppIndicator3.Indicator.new( "desktop-agenda", "gnome-calendar", AppIndicator3.IndicatorCategory.OTHER) self.appindicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) # Create the dropdown menu for the taskbar icon menu = Gtk.Menu() item_show_hide = Gtk.MenuItem("Hide") item_show_hide.connect("activate", self.show_or_hide) item_refresh = Gtk.MenuItem("Refresh") item_refresh.connect("activate", self.refresh_agenda) item_prefs = Gtk.MenuItem("Preferences") item_prefs.connect("activate", self.show_prefs) item_quit = Gtk.MenuItem("Quit") item_quit.connect("activate", self.quit) menu.append(item_show_hide) menu.append(item_refresh) menu.append(item_prefs) menu.append(item_quit) menu.show_all() self.appindicator.set_menu(menu) # Create an instance of the GoogleCalendar class # TODO: This can raise an exception # google.auth.exceptions.RefreshError: # ('invalid_grant: Bad Request', u'{\n "error": "invalid_grant",\n "error_description": "Bad Request"\n}') # In this case, the token.pickle file needs to be removed self.calendar = GoogleCalendar() # Initialize the main window Gtk.Window.__init__(self) self.set_title("Desktop Agenda") screen = self.get_screen() visual = screen.get_rgba_visual() if visual is None: visual = screen.get_system_visual() self.set_visual(visual) # Load CSS styles from config file if os.path.exists(CSS_SOURCE): css = Gtk.CssProvider() css.load_from_path(CSS_SOURCE) Gtk.StyleContext.add_provider_for_screen( screen, css, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Set window options self.set_decorated(False) self.set_position(Gtk.WindowPosition.NONE) self.set_resizable(False) self.set_accept_focus(False) self.set_keep_below(True) self.set_skip_taskbar_hint(True) self.set_app_paintable(True) # Connect some event handlers to the window for custom behavior self.connect("delete-event", Gtk.main_quit) self.connect("enter-notify-event", self.enter_notify) self.connect("leave-notify-event", self.leave_notify) # Create window layout self.widgets_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.widgets_container.get_style_context().add_class("container") self.add(self.widgets_container) clock_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.widgets_container.pack_start(clock_container, True, True, 0) self.time_lbl = Gtk.Label(xalign=0) self.time_lbl.get_style_context().add_class("lbl") self.time_lbl.get_style_context().add_class("time-lbl") clock_container.pack_start(self.time_lbl, False, False, 0) self.date_lbl = Gtk.Label(xalign=0) self.date_lbl.get_style_context().add_class("lbl") self.date_lbl.get_style_context().add_class("date-lbl") clock_container.pack_start(self.date_lbl, False, False, 0) # Update clock and calendar at startup self.update_clock() self.update_agenda(force=True) # Create timers to update clock and calendar at fixed time intervals GObject.timeout_add(1000, self.update_clock) GObject.timeout_add(1000, self.update_agenda) GObject.timeout_add(1000, self.reminders) def position(self): screen = self.get_screen() window_size = self.get_size() self.move(screen.width() - window_size.width, 0) def date_handler(self, date): """ This date handler creates a new label containing the specified date. This function may return False to cancel further processing of events. Return True to allow processing of events to continue. """ dt = parse(date) # Do not create a date label because current date label already exists if dt.date() == datetime.today().date(): return True # TODO: If creating a date label and one event label would exceed bottom of # screen, set a flag indicating this and return False to prevent further # processing. The challenge is in keeping track of where the last label was # placed relative to the height of the screen. # if self.screenMaxReached: # return lbl = Gtk.Label(dt.strftime(CLOCK_DATE_FORMAT), xalign=0) lbl.get_style_context().add_class("lbl") lbl.get_style_context().add_class("date-header-lbl") self.event_container.attach(lbl, 0, self.row, 2, 1) self.row += 1 return True def event_handler(self, event): """ This event handler creates labels for a calendar event. The label will be created with mouse-over tooltip containing the location and name of the meeting organizer. A click handler is also created to open the event in a web browser. This function may return False to cancel further processing of events. Return True to allow processing of events to continue. """ # Useful event fields: # event["status"] - "confirmed" # event["htmlLink"] - "https://www.google.com/calendar/event?eid=xxxxxxxx" # event["summary"] - "Status Meeting" # event["start"] - {dateTime: 2019-03-21T10:00:00-07:00} # TODO: event["datetime"] - event["start"] parsed into a Python DateTime object # event["location"] - "Conference Room" # event["organizer"] - {email : [email protected]} # event["creator"] - {email : [email protected]} # TODO: If creating an event label would exceed bottom of screen, set a # flag indicating this and return # if self.screenMaxReached: # return title = event.get("summary", "(No title)") ev_time = "" location = event.get("location", "(No location)") organizer = event.get("organizer", event.get("creator", None)) if organizer is not None: organizer = organizer.get("displayName", organizer.get("email", None)) html_link = event.get("htmlLink", None) date = event["start"].get("dateTime", None) if date is not None: dt = parse(date) ev_time = dt.strftime(TIME_LBL_FORMAT) time_lbl = Gtk.Label(xalign=0) time_lbl.set_halign(Gtk.Align.END) lbl_color = event.get("color", None) # print lbl_color if lbl_color is not None: time_lbl.set_markup("<span foreground='{}'>{}</span>".format( event["color"], ev_time)) time_lbl.get_style_context().add_class("lbl") time_lbl.get_style_context().add_class("event-time-lbl") self.event_container.attach(time_lbl, 0, self.row, 1, 1) title_lbl = Gtk.Label(title, xalign=0) title = title.replace("&", "&") if lbl_color is not None: title_lbl.set_markup("<span foreground='{}'>{}</span>".format( event["color"], title.encode("utf-8"))) # Set tooltip tooltip_text = "Location: {}".format(location.encode("utf-8")) if organizer is not None: tooltip_text = "{}\nOrganizer: {}".format( tooltip_text, organizer.encode("utf-8")) title_lbl.set_tooltip_text(tooltip_text) # Set label style title_lbl.get_style_context().add_class("lbl") title_lbl.get_style_context().add_class("event-title-lbl") # Create a click event handler to open the event in a web browser # This handler is unique to this label so it is defined as an inner function def lbl_click_handler(widget, event): Gtk.show_uri(None, html_link, time.time()) # Create a container that will handle user interaction event_box = Gtk.EventBox() event_box.connect("button-press-event", lbl_click_handler) # The mouse enter and leave events need to pass through to the main window event_box.connect("enter-notify-event", self.event_lbl_enter) event_box.connect("leave-notify-event", self.event_lbl_leave) event_box.add(title_lbl) # Add the new label to the window layout self.event_container.attach(event_box, 1, self.row, 1, 1) self.row += 1 return True def _reminder_handler(self, event): """ Checks if the given event has a notification that needs to be shown and creates a taskbar notification if necessary. This function may return False to cancel further processing of events. Return True to allow processing of events to continue. """ date = event["start"].get("dateTime", None) if date is None: return True dt = parse(date).astimezone(pytz.utc) now = datetime.now(pytz.utc).replace(second=0, microsecond=0) for reminder in event["reminders"]: method = reminder.get("method", None) if method is None or method != "popup": continue minutes = reminder.get("minutes", 0) if minutes <= 0: continue reminder_time = dt - timedelta(minutes=minutes) if reminder_time == now: # TODO: Create popup notification print "popup" return False # Only create one popup and cancel further event handlers return True def event_lbl_enter(self, widget, event): pointer = Gdk.Cursor( Gdk.CursorType.HAND1) # TODO: should pointer be a class variable? wnd = self.get_root_window() wnd.set_cursor(pointer) self.enter_notify(widget, event) return False def event_lbl_leave(self, widget, event): # TODO: Is this the best way to restore the default cursor? # We don't know what user's default cursor is set to. Shouldn't assume ARROW pointer = Gdk.Cursor(Gdk.CursorType.ARROW) wnd = self.get_root_window() wnd.set_cursor(pointer) return False def update_clock(self): # TODO: Attempted to decouple clock label updates from agenda updates. # If API is unreachable because there is no internet connection, # the clock labels stop updating. This is unconfirmed hypothesis now = datetime.now() now_utc = datetime.now(pytz.utc) time_str = now.strftime(CLOCK_TIME_FORMAT) time_utc_str = now_utc.strftime(CLOCK_UTC_FORMAT) date_str = now.strftime(CLOCK_DATE_FORMAT) self.time_lbl.set_text(time_str) self.time_lbl.set_tooltip_text(time_utc_str) self.date_lbl.set_text(date_str) return True def update_agenda(self, force=False): """ Updates the entire adenda window This function should return True so the timer will continue to run. Returning False will cancel the timer. """ now = datetime.now() # TODO: Use a timeout for API requests in google_calendar.py if (now.second == 0 and now.minute % 15 == 0) or force: # Synchronous API query self.calendar.load_events( days=self.prefs_window.get_query_days(), max_results=self.prefs_window.get_query_limit()) # Remove all event labels if self.event_container is not None: self.event_container.destroy() self.row = 0 # Create new labels self.event_container = Gtk.Grid() self.widgets_container.pack_start(self.event_container, True, True, 0) self.calendar.get_events(self.date_handler, self.event_handler) self.show_all() return True def reminders(self): now = datetime.now() if now.second == 0: self.calendar.get_events(None, self._reminder_handler) return True def enter_notify(self, event, data): self.set_keep_below(False) self.set_keep_above(True) return False def leave_notify(self, event, data): self.set_keep_above(False) self.set_keep_below(True) return False def show_or_hide(self, event): """ Toggle the visibility of the main window. """ visible = self.get_property("visible") if visible: self.hide() event.set_label("Show") else: # TODO: There is a bug here, the window does not appear in the # correct location after being hidden and shown again self.show() event.set_label("Hide") def refresh_agenda(self, event): self.update_agenda(force=True) def show_prefs(self, event): """ Menu handler to show the preferences window. """ # TODO: Preferences window layout is not complete self.prefs_window.show_all() return def quit(self, event): Gtk.main_quit()
# The URL of the GitHub page with Accent's source code. CODE_URL = 'https://github.com/maxbbraun/accent' # The URL of the Accent Twitter profile. SOCIAL_URL = 'https://twitter.com/AccentInk' # The template for editing user data. HELLO_TEMPLATE = 'hello.html' # A geocoder instance with a shared cache. geocoder = Geocoder() # Helper library instances. artwork = Artwork() calendar = GoogleCalendar(geocoder) city = City(geocoder) commute = Commute(geocoder) everyone = Everyone(geocoder) schedule = Schedule(geocoder) # The Flask app handling requests. app = Flask(__name__) @app.route('/artwork') @user_auth(image_response=gif_response) def artwork_gif(key=None, user=None): """Responds with a GIF version of the artwork image.""" width, height = display_size(request)
def __init__(self): self.row = 0 self.event_container = None self.prefs_window = prefs.PrefsWindow() # Initialize the taskbar icon self.appindicator = AppIndicator3.Indicator.new( "desktop-agenda", "gnome-calendar", AppIndicator3.IndicatorCategory.OTHER) self.appindicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) # Create the dropdown menu for the taskbar icon menu = Gtk.Menu() item_show_hide = Gtk.MenuItem("Hide") item_show_hide.connect("activate", self.show_or_hide) item_refresh = Gtk.MenuItem("Refresh") item_refresh.connect("activate", self.refresh_agenda) item_prefs = Gtk.MenuItem("Preferences") item_prefs.connect("activate", self.show_prefs) item_quit = Gtk.MenuItem("Quit") item_quit.connect("activate", self.quit) menu.append(item_show_hide) menu.append(item_refresh) menu.append(item_prefs) menu.append(item_quit) menu.show_all() self.appindicator.set_menu(menu) # Create an instance of the GoogleCalendar class # TODO: This can raise an exception # google.auth.exceptions.RefreshError: # ('invalid_grant: Bad Request', u'{\n "error": "invalid_grant",\n "error_description": "Bad Request"\n}') # In this case, the token.pickle file needs to be removed self.calendar = GoogleCalendar() # Initialize the main window Gtk.Window.__init__(self) self.set_title("Desktop Agenda") screen = self.get_screen() visual = screen.get_rgba_visual() if visual is None: visual = screen.get_system_visual() self.set_visual(visual) # Load CSS styles from config file if os.path.exists(CSS_SOURCE): css = Gtk.CssProvider() css.load_from_path(CSS_SOURCE) Gtk.StyleContext.add_provider_for_screen( screen, css, Gtk.STYLE_PROVIDER_PRIORITY_USER) # Set window options self.set_decorated(False) self.set_position(Gtk.WindowPosition.NONE) self.set_resizable(False) self.set_accept_focus(False) self.set_keep_below(True) self.set_skip_taskbar_hint(True) self.set_app_paintable(True) # Connect some event handlers to the window for custom behavior self.connect("delete-event", Gtk.main_quit) self.connect("enter-notify-event", self.enter_notify) self.connect("leave-notify-event", self.leave_notify) # Create window layout self.widgets_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.widgets_container.get_style_context().add_class("container") self.add(self.widgets_container) clock_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.widgets_container.pack_start(clock_container, True, True, 0) self.time_lbl = Gtk.Label(xalign=0) self.time_lbl.get_style_context().add_class("lbl") self.time_lbl.get_style_context().add_class("time-lbl") clock_container.pack_start(self.time_lbl, False, False, 0) self.date_lbl = Gtk.Label(xalign=0) self.date_lbl.get_style_context().add_class("lbl") self.date_lbl.get_style_context().add_class("date-lbl") clock_container.pack_start(self.date_lbl, False, False, 0) # Update clock and calendar at startup self.update_clock() self.update_agenda(force=True) # Create timers to update clock and calendar at fixed time intervals GObject.timeout_add(1000, self.update_clock) GObject.timeout_add(1000, self.update_agenda) GObject.timeout_add(1000, self.reminders)