Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

Python System Tray Python app issue with building a list.

splaq

Coder
I am working on an app right now that is basically google calendar in your system tray, I'm running into the issue in the build_calendar_list() method. I'll post the code below, but everything works the way I would expect until I choose a calendar from my list of calendars. When I choose a calendar I expect to get back the calendar id of the chosen calendar. But I only ever get back the the id for the last item in the list. That's a very basic idea of the program and the problem.. Here is the code..
Python:
from __future__ import print_function

import datetime
import os.path
import pprint
import sys

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

from PIL import Image
from pystray import Icon as icon, Menu as menu, MenuItem as item


# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/calendar']

class MyCalendar:
    def __init__(self):
        """Shows basic usage of the Google Calendar API.
            Prints the start and name of the next 10 events on the user's calendar.
        """
        self.creds = None
        # The file token.json stores the user's access and refresh tokens, and is
        # created automatically when the authorization flow completes for the first
        # time.
        if os.path.exists('token.json'):
            self.creds = Credentials.from_authorized_user_file('token.json', SCOPES)
        # If there are no (valid) credentials available, let the user log in.
        if not self.creds or not self.creds.valid:
            if self.creds and self.creds.expired and self.creds.refresh_token:
                self.creds.refresh(Request())
            else:
                flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials.json', SCOPES)
                self.creds = flow.run_local_server(port=0)
            # Save the credentials for the next run
            with open('token.json', 'w') as token:
                token.write(self.creds.to_json())

        try:
            # Call the Calendar API
            self.service = build('calendar', 'v3', credentials=self.creds)
            self.cal_id = None
            self.cal_list = self.build_calendar_list()
            print(dir(self.cal_list[0]))


        except HttpError as error:
            print('An error occurred: %s' % error)


    # def get_events(self):
    #     now = datetime.datetime.utcnow().isoformat() + 'Z'  # 'Z' indicates UTC time

    #     events_result = self.service.events().list(calendarId=self.get_cal_id(), timeMin=now,
    #                                         maxResults=10, singleEvents=True,
    #                                         orderBy='startTime').execute()
    #     events = events_result.get('items', [])

    #     if not events:
    #         print('No upcoming events found.')
    #         return

    #     # Prints the start and name of the next 10 events
    #     for event in events:
    #         start = event['start'].get('dateTime', event['start'].get('date'))
           
    #         print(start, event['summary'])

    def set_cal_id(self, cal_id):
        self.cal_id = cal_id
        print(self.cal_id)
        # return self.cal_id
   
    def get_cal_id(self):
        return self.cal_id


    def tray_icon(self):
        image = Image.open("icon.ico")
        return image

    def good_bye(self, icon):
        print("Later Tater!")
        icon.visible = False
        icon.stop()

    def create_tray(self):
        '''
        Create the tray icon & menu
        '''
        menu_items = tuple(self.cal_list)
        icon(
            'TrayCalendar',
            icon=self.tray_icon(),
            menu=menu(
                item(
                    'Quit',
                    self.good_bye,
                ),
                item(
                    'Calendar List',
                    menu(
                        lambda: (item for item in menu_items)
                    ),
                ),
            ),
        ).run()

    def build_calendar_list(self):
        '''
        Build the list of calendars in the users Google Calendar
        '''
        cal_list = []
        calendarlist = self.service.calendarList().list().execute()

        for k in calendarlist.get('items', tuple()):

            cal_list.append(
                ## ISSUE:
                ## All k['id'] come back as the last item in the list.
                ## IE. All lambda: self.set_cal_id(k['id']) => lambda: self.set_cal_id('addressbook#[email protected]')
                ## 0 understanding as to why.
                (item(k["summary"], lambda *args: self.set_cal_id(k['id'])))
            )
       
        return cal_list


if __name__ == '__main__':
    my_cal = MyCalendar()
    my_cal.create_tray()

I believe what's going on is that for whatever reason the lambda function in my build_calendar_list() method is causing all of my id's to default to the last item in the list of calendars. If that's the case then what can I do to correct that? The idea is to be able to choose a calendar and get a quick view of events for that calendar or add an event etc.
 

New Threads

Buy us a coffee!

Back
Top Bottom