Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- from __future__ import print_function #IMPORTING ALL LIBRARIES....
- from tkinter import * #TKINTER ALLOWS FOR WINDOWS
- import tkinter #TKINTER ALLOWS FOR WINDOWS
- from PIL import Image #ALLOWS OUTPUT OF IMAGING IN A WINDOW
- from PIL import ImageTk #ALLOWS OUTPUT OF IMAGING IN A WINDOW
- import time #GIVES THE TIME
- import pyowm #ALLOWS FOR CONNECTION TO WEATHER API
- from pyowm import OWM #ALLOWS FOR CONNECTION TO WEATHER API
- import datetime #GIVES THE DATE
- from googleapiclient.discovery import build #ALLOWS FOR CONNECTION TO GOOGLE API WHICH ALLOWS ACCESS TO CALENDAR
- from httplib2 import Http #ALLOWS FOR CONNECTION TO GOOGLE API
- from oauth2client import file, client, tools #ALLOWS FOR CONNECTION TO GOOGLE API
- import pygame
- import subprocess
- pygame.init()
- #SETTING SOME GLOBAL VARIABLES...
- event1 = [1] #THIS IS DONE SO THAT WITHIN THE FIRST CYCLE OF CALENDAR event1 IS DEFINED AND IT DOES NOT EQUAL NULL, AS IF events_1 AND events = NULL IN THE FIRST CYCLE NO RMEINDERS WON'T BE DISPLAYED
- y = 2
- finalStatus2 = ''
- timeString = ''
- month = [' January',' Febuary',' March',' April',' May',' June',' July',' August',' September',' October',' November',' December']
- def calender():
- global timeString
- def main(): #THIS ALLOWS ME TO USE IF MAIN == NAME WHICH ALLOWS THE CODE IN THE MODULE TO BE IMPOTABLE BY OTHER MODULES
- tmrw = datetime.date.today() + datetime.timedelta(days=1) #TMRW WILL HOLD TOMMOROWS DATE#
- tmrw = str(tmrw) #TMRW IS TURNED TO A STRING AS ITS OLD DATA TYPE COULD NOT BE SHORTENED USING [:X]
- x = 20 #THIS IS THE STARTING ROW AT WHICH THE REMINDERS ARE OUTPUTTED
- global event1 #BRINGING IN A GLOBAL VARIABLE TO THE PROCEDURE
- global y #BRINGING IN A GLOBAL VARIABLE TO THE PROCEDURE
- store = file.Storage('token.json') #TOKEN.JSON IS STORED IN THIS DIRECTORY
- creds = store.get() #GETS JSON FILE
- if not creds or creds.invalid:
- flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
- creds = tools.run_flow(flow, store)
- service = build('calendar', 'v3', http=creds.authorize(Http())) # Call the Calendar API
- now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time, NOW WILL HOLD THE TIME
- eventsResult = service.events().list(calendarId='primary', timeMin=now, #GETS THE NEXT 10 EVENTS
- maxResults=10, singleEvents=True,
- orderBy='startTime').execute()
- start_date = time.strftime('20%y-%m-%d') #GETS THE CURRENT DATE IN THE FORM YYYY-MM-DD
- date1 = datetime.datetime.strptime(start_date,'20%y-%m-%d') #THIS IS DONE SO I CAN APPLY A DATETIME METHOD TO DATE1
- z = False
- if timeString == '12: 01 AM': #Z WILL BE TRUE WHEN IT IS 00:01
- z = True #THIS IS DONE TO RE WRITE EVENTS WHEN THE DAY HAS CHANGED AS TOMMOROW REMINDERS WILL BECOME TODAY REMINDERS AND TODAY REMINDERS WILL VANISH
- events = eventsResult.get('items', []) #REFORMATS eventsResult TO REOMVE IRRELEVANT DATA
- if event1 != events or z == True: #IF THE LIST OF EVENTS HAS CHANGED OF IF IT'S 00:01
- sound = pygame.mixer.Sound("sound.wav") #LOAD THE FILE sound.wav TO sound SO IT CAN BE PLAYED
- sound.play() #PLAY SOUND.WAV
- for event in event1: #THE NUMBER OF EVENTS BEFORE A CHANGE IN EVENTS IS THE NUMBER OF BLANKS OUTPUTTED TO COVER UP THE EXACT NUMBER OF PREVIOUS EVENTS
- the_event = ' ' #THE_EVENT HOLDS A LONG SPACE WHICH WHEN OUTPUTTED WILL COVER UP THE PREVIOUS OUTPUTS OF EVENT
- Label (window, text= the_event, bg='black', fg='black', font=('times', 32)) .grid(row=x, column=2, sticky=W) #OUTPUTS MESSAGE IN BLACK IN ORDER TO COVER UP PREVIOUS MEESAGE IN WHITE SO EVENTS DONT WRITE OVER EACH OTHER
- x = x+1 #SO THE NEXT LABEL IS OUTPUTTED ON THE NEXT ROW
- x = 1 #SO X DOES NOT EQUAL 20 AND NO REMINDRRS ISNT DISPLAYED WHEN THERE ARE REMINDERS
- if event1 != events or z == True: #IF THE LIST OF EVENTS HAS CHANGED OF IF IT'S 00:01
- x = 20 #THIS IS TO OUTPUT EACH EVENT ON A DIFFERENT LINE STARTING WITH 11
- event1 = events #THIS IS DONE SO I CAN CHECK IF THERE HAS BEEN A CHANGE TO THE CALENDAR FOR THE NEXT ITERATION OF MAIN()
- if events != [] and y == 1: #IF THERE IS SOMETHING IN EVENTS AND 'NO REMINDERS' WAS OUTPUTTED LAST ITERATION OF MAIN()
- Label (window, text=' No upcoming reminders found', bg='black', fg='black', font=('times', 32)) .grid(row=20, column=2, sticky=W) #COVER PREVIOUS OUTPUT OF NO UPCOMING REMINDERS FOUND
- for event in events: #REPEAT THIS FOR EACH EVENT IN EVENTS
- g = False #SETTING VARIABLES TO FALSE SO THEY CAN BE COMPARED IF THEY ARE NOT CHANGED TO TRUE
- today2 = False
- tmrw2 = False
- start = event['start'].get('dateTime', event['start'].get('date')) #START IS A TUPLE COUNTAINING THE START TIME (IF THERE IS ONE) OF THE EVENT AND THE START DATE
- for i in range (2,7): #THIS LOOP CHECKS IF THE REMINDER IS IN THE NEXT 6 DAYS (BUT NOT TOMMOROW)
- date2 = date1 + datetime.timedelta(days=i) #DATE2 WILL HOLD THE DATE OF TODAY PLUS i DAYS
- date2 = str(date2) #CHANGING DATE2 TO A STRING SO THAT THE NEXT LINE OF CODE CAN WORK
- date2 = date2[:10]
- if date2 == start[:10]: #IF DATE2 IS THE SAME DAYE OF THE EVENT
- year, month, day = (int(e) for e in date2.split('-')) #REFORMATTING EVENT SO I CAN EXTRACT THE DAY
- ans = datetime.date(year, month, day) #APPLYING THE DATETIME METHOD SO THE NEXT LINE WILL WORK
- dow = (ans.strftime('%A')) #GET THE DAY OF DATE2 (E.G. THURSDAY, SUNDAY ....)
- g = True
- if now[:10] == start[:10]: #IF THE EVENT IS TODAY
- today2 = True
- elif tmrw[:10] == start[:10]: #IF THE EVENT IS TOMMORW
- tmrw2 = True
- if 'summary' in event:
- the_event = (start, event['summary'],' ') #EVENT SUMMARY IS THE DESCRIPTION OF THE EVENT (E.G. DENTISTS APPOINTMENT)
- else:
- the_event = (start, 'no title',' ') #HERE I HAVE VALIDATED MY PROGRAM AS IF THE CLIENT HAS NOT ENTERED A TITLE MY PROGRAM WON'T CRASH
- if 'T' in the_event[0]: #IF THE EVENT HAS A SPECIFIC TIME
- start = start.split('T') #SPLIT START INTO THE DATE AND TIME
- date = start[0][5:] #FIRST 5 CHARACTER OF START[0] ARE MM-DD
- time3 = ' '+start[1][:5] #TIME88 IT RE-WRITTEN IN THE FORM HH-MM (IF HAVE USED TIME88 INSTEAD OF TIME AS TIME. IS A METHOD AND THAT CAN CONFUSE PYTHON SOMETIMES)
- if today2 == True: #IF THE EVENT IS TODAY
- date = '*TODAY*'
- elif tmrw2 == True: #IF THE EVENT IS TOMORROW
- date = 'Tomorrow'
- elif g ==True: #IF THE EVENT IS WITHIN THE NEXT 6 DAYS (NOT INCLUDING TOMORROW)
- date = dow #THE DAY OF THE WEEK OF THE REMINDER IS PUT IN TO DATE
- else: #DEPENDING ON THE MONTH DATE IS CHANGED SO THE MONTH IS WRITTEN AND THE DAY IS AN NUMBER IN THE FORM DD MMM..
- date = monthh(date) #THE FUNCTION MONTH RETURNS THE MONTH FOR A GIVEN DATE IN WRITTEN FORM
- the_event = ' ' + date + ': ' + the_event[1] + time3
- else: #IF THE REMINDER IS AN ALL DAY REMINDER (NO TIME)
- date = start[5:] #REFORMATS DATE TO MM-DD
- if today2 == True: #IF THE EVENT IS TODAY
- date = '*TODAY*'
- elif tmrw2 == True: #IF THE EVENT IS TOMORROW
- date = 'Tomorrow'
- elif g ==True: #IF THE EVENT IS WITHIN THE NEXT 6 DAYS (NOT INCLUDING TOMORROW)
- date = dow #THE DAY OF THE WEEK OF THE REMINDER IS PUT IN TO DATE
- else: #DEPENDING ON THE MONTH DATE IS CHANGED SO THE MONTH IS WRITTEN AND THE DAY IS AN NUMBER IN THE FORM DD MMM..
- date = monthh(date) #THE FUNCTION MONTH RETURNS THE MONTH FOR A GIVEN DATE IN WRITTEN FORM
- the_event = ' ' + date + ': ' + the_event[1] #the_event HOLDS ALL THE INFORMATION THAT WILL GO UP AS A REMINDER FOR A PARTICULAR EVENT
- if today2 == True: #IF THE EVENT IS TODAY IT WILL BE RED, IF IT IS TOMOROW IT WILL BE PINK, AND IF NONE IT WILL BE WHITE
- color = 'red2'
- elif tmrw2 == True:
- color = 'deep pink'
- else:
- color = 'white'
- Label (window, text= the_event, bg='black', fg= color, font=('times', 32)) .grid(row=x, column=2, sticky=W) #OUTPUTS THE EVENT
- x = x+1 #ADDS 1 TO X SO NEXT REMINDER IS ON THE NEXT ROW
- y = 0 #Y IS SET TO 0 SO MY FUNCTION KNOWS THAT THERE ARE REMINDERS (EVENTS != NULL)
- if x == 20: #X WILL ONLY=20 WHEN X HAS NOT BEEN INCREMENTED MEANING EVENTS IS EMPTY AND HERE HAS BEEN A CHANGE IN EVENTS
- Label (window, text=' No upcoming reminders found', bg='black', fg='white', font=('times', 32)) .grid(row=20, column=2, sticky=W) #OUTPUTS No upcoming reminders found
- y = 1 #Y IS SET TO 1 SO MY FUNCTION KNOWS THAT THERE ARE NO REMINDERS (EVENTS == NULL)
- if __name__ == '__main__':
- main()
- window.after(2000, calender) #REPEATS EVERY 900000 MILISECONDS
- def remind():
- def main2():
- store = file.Storage('token.json') #TOKEN.JSON IS STORED IN THIS DIRECTORY
- creds = store.get() #GETS JSON FILE
- if not creds or creds.invalid:
- flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
- creds = tools.run_flow(flow, store)
- service = build('calendar', 'v3', http=creds.authorize(Http())) # Call the Calendar API
- now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time, NOW WILL HOLD THE TIME
- eventsResult = service.events().list(calendarId='primary', timeMin=now, #GETS THE NEXT 10 EVENTS
- maxResults=10, singleEvents=True,
- orderBy='startTime').execute()
- events = eventsResult.get('items', []) #REFORMATS eventsResult TO REMOVE IRRELEVANT DATA
- timeString1 = time.strftime('%H: %M') #timeString1 WILL HOLD THE TIME IN 24HR HH:MM
- hour = int(timeString1[:2]) #hour IS AN INTEGER WHICH HOLDS THE CURRENT HOUR BY TAKING THE FIRST TWO VALUES OF timeString1
- minute = int(timeString1[4:]) #minute IS AN INTEGER WHICH HOLDS THE CURRENT minute BY TAKING THE last TWO VALUES OF timeString1
- a = datetime.datetime(100, 1, 1, hour, minute, 00) #a HOLDS THE TIME, I DID THE PREVIOUS TWO STEPS SO I COULD APPLY THE DATETIME METHOD TO THE TIME SO THAT I CAN ADD TIME TOGETHER (SHOWN BELOW). AFTER MINUTE THE 00 SETS THE SECONDS TO 0
- b = a + datetime.timedelta(minutes=5) #b HOLDS THE TIME & DATE IN 5 MINUTES
- c = a + datetime.timedelta(minutes=10) #c HOLDS THE TIME & DATE IN 10 MINUTES
- b = str(b.time()) #b HOLDS THE TIME IN 5 MINUTES AS A STRING IN THE FORM HH:MM:SS WHERE SS == 00
- c = str(c.time()) #c HOLDS THE TIME IN 5 MINUTES AS A STRING IN THE FORM HH:MM:SS WHERE SS == 00
- for event2 in events: #FOR ALL OF THE NEXT 10 EVENTS IN GOOGLE CALENDAR (IN ASCENDING ORDER OF TIME)
- if 'summary' in event2: #IF THE EVENT HAS A SUMMARY
- the_summary = event2['summary'] #PUT THE SUMMARY OF THE EVENT IN the_summary
- if the_summary.endswith('!'): #IF THE SUMMARY ENDS WITH A '!'
- if 'dateTime' in event2['start']: #IF THE EVENT HAS A TIME
- getTime = (event2['start'])['dateTime'] #PUT THE TIME & DATE OF THE EVENT IN getTime
- getTime = getTime.split('T') #SPLIT getTime INTO THE DATE AND TIME
- getTime = getTime[1][:5] #getTime IT RE-WRITTEN IN THE FORM HH-MM
- getTime = getTime + ':00' #ADDING THE SECONDS (SS) SO THAT b AND c CAN BE COMPARED WITH getTime
- getTime = str(getTime) #TURN getTime INTO A STRING SO IT CAN BE COMPARED WITH a & b
- if getTime == b or getTime == c: #IF THE EVENT IS IN 5 OR 10 MINUTES
- sound = pygame.mixer.Sound("alert.wav") #PUT THE sound.wav FILE INTO SOUND
- sound.play() #PLAY THE SOUND
- if __name__ == '__main__':
- main2()
- window.after(57000, remind) #REPEATS EVERY 900000 MILISECONDS
- def monthh(date):
- global month #RETRIEVES LIST OF MONTHS
- theMonth = int(date[:2]) #TURNS THE MONTH E.G. 04 INTO AN INT SO IT BECOMES 4
- for i in range (0,12): #LOOP FOR EACH MONTH
- if theMonth == i+1: #IF THE CURRENT MONTH IS i + 1
- date = str(int(date[3:])) + month[i] #PUT THE DAY AND MONTH INTO DATE
- break #SO THE LOOP DOESNT CARRY ON WHEN THERE IS NOTHING TO DO
- return date
- def tick():
- global timeString
- timeString = time.strftime('%I: %M %p') #HOUR MINUTE (LAYOUT) THIS IS THE TIME
- clock.config(text=timeString)
- clock.after(10000, tick) #REPEATS EVERY 60000 MILISECONDS
- now = datetime.datetime.now()
- hour = now.hour
- if hour == 23:
- subprocess.call(['./killmirror.sh'])
- def day():
- day1 = time.strftime('%A') #ONLY SELECTS THE DAY FROM TIME
- dayOfTheWeek.config(text=day1)
- dayOfTheWeek.after(800000, day) #REPEATS EVERY 800000 MILISECONDS
- def date():
- date1 = time.strftime('%b %d, %Y') #GETS THE CURRENT DATE IN THE FORM MONTH D Y
- date2.config(text=date1)
- date2.after(800000, date) #REPEATS EVERY 800000 MILISECONDS
- def weather():
- global finalStatus2 #BRINGING IN A GLOBAL VARIABLE TO THE PROCEDURE
- blank = Label(window, text= ' ', bg='black', fg='black', font=('times', 23)) #OUTPUTS TEMPERATURE
- blank.place(x=1080, y=147) #PLACES THE LABEL AT THE CORRESPONDING CO-ORDINATES
- blank2 = Label(window, text= ' ', bg='black', fg='black', font=('times', 23)) #OUTPUTS TEMPERATURE
- blank2.place(x=1080, y=180) #PLACES THE LABEL AT THE CORRESPONDING CO-ORDINATES
- try:
- owm = pyowm.OWM('9e9c1df91cf57fd15c67f2b883e7c9ee') #API USED TO CONNECT TO WEATHER SERVICES OVER THE INTERNET
- except:
- try:
- owm = pyowm.OWM('b039fd94b6d27892dd194866a0077fdb') #API USED TO CONNECT TO WEATHER SERVICES OVER THE INTERNET
- except:
- try:
- owm = pyowm.OWM('2399c51c67515a394b74e834149aea2a') #API USED TO CONNECT TO WEATHER SERVICES OVER THE INTERNET
- except:
- print('error, weather not working')
- observation = owm.weather_at_place('New Malden,GB')
- Weather_info = observation.get_weather() #GET WEATHER INFORMATION
- temp_info = Weather_info.get_temperature('celsius') #GET INFORMATION ABOUT TEMPERATURE IN CELCIUS
- y = str(Weather_info) #TURNING WEATHER INFORMATION TO A STRING SO I CAN SEARCH WITHIN THE VARIABLE
- find = y.find('detailed') #SEARCHING FOR SPECIFIC INFORMATION WITHIN THE WEATHER INFORMATION...
- status = y[(find-2):] #REFINING Y TO GET THE WEATHER...
- status2 = status.find('status=') #REFINING STATUS TO GET THE WEATHER...
- status = status[(status2+7):] #REFINING STATUS2 TO GET THE WEATHER...
- finalStatus1 = status.rstrip('>') #finalStatus1 HOLDS THE CURRENT WEATHER
- temp = temp_info['temp'] #'temp' IS THE ACTUAL TEMPERATURE
- temp = float(temp) #MODIFYING TEMP...
- temp = round(temp, 0 )
- temp = str(temp)
- temp = temp[:-2]
- temp = temp +' celsius'
- finalStatus2 = finalStatus1.strip()
- #OUTPUTS:
- temp1 = Label(window, text= temp, bg='black', fg='white', font=('times', 23)) #OUTPUTS TEMPERATURE
- temp1.place(x=1080, y=147) #PLACES THE LABEL AT THE CORRESPONDING CO-ORDINATES
- temp1.after(1500000, weather) #REPEATS EVERY 25 MINUTES
- def pic():
- global finalStatus2 #BRINGING IN A GLOBAL VARIABLE TO THE PROCEDURE
- global timeString #BRINGING IN A GLOBAL VARIABLE TO THE PROCEDURE
- time1 = int(timeString[:2]) #TIME HOLDS THE TIME IN THE FORM HH
- time2 = timeString[7:] #TIME2 HOLDS EITHER AM OR PM
- if 12 > time1 > 6 and time2 == 'PM' or time1 < 6 and time2 == 'AM' or time1 == 12 and time2 == 'AM': #IF ITS DARK OUTSIDE:
- if 'drizzle' in finalStatus2 or 'rain' in finalStatus2:
- photo = Image.open('assets/Rain.png')
- elif 'thunderstorm' in finalStatus2:
- photo = Image.open('assets/Storm.png')
- elif 'snow' in finalStatus2 or 'sleet' in finalStatus2:
- photo = Image.open('assets/Snow.png')
- else:
- photo = Image.open('assets/Moon.png')
- else:
- if finalStatus2 =='mist' or finalStatus2 =='haze' or finalStatus2 =='smoke' or finalStatus2 =='sand, dust whirls' or finalStatus2 =='fog' or finalStatus2 =='sand' or finalStatus2 =='dust' or finalStatus2 =='volcanic ash' or finalStatus2 =='squalls' or finalStatus2 =='tornado':
- photo = Image.open('assets/Haze.png')
- elif 'drizzle' in finalStatus2 or 'rain' in finalStatus2:
- photo = Image.open('assets/Rain.png')
- elif 'thunderstorm' in finalStatus2 == True:
- photo = Image.open('assets/Storm.png')
- elif 'clouds' in finalStatus2:
- if finalStatus2 =='few clouds' or finalStatus2 =='scattered clouds':
- photo = Image.open('assets/PartlySunny.png')
- else:
- photo = Image.open('assets/Cloud.png')
- elif finalStatus2 == 'clear sky':
- photo = Image.open('assets/Sun.png')
- elif 'snow' in finalStatus2 or 'sleet' in finalStatus2:
- photo = Image.open('assets/Snow.png')
- else:
- photo = Image.open('assets/PartlySunny.png')
- #OUTPUTS THE PHOTO:
- photo = photo.resize((100,100), Image.ANTIALIAS) #RESIZES IMAGE
- photo = ImageTk.PhotoImage(photo)
- photo1 = Label(window, image=photo, bg = 'black')
- photo1.photo = photo
- photo1.place(x=1300, y=40) #PLACES THE LABEL AT THE CORRESPONDING CO-ORDINATES
- photo1.after(1500000, pic) #REPEATS EVERY 25 MINUTES
- #CREATES A WINDOW
- window = Tk() #CREATES A WINDOW
- window.title('My Smart Mirror') #NAMES THE WINDOW
- window.configure(background='black') #SETS BACKGROUND OF THE WINDOW TO BLACK
- window.attributes('-fullscreen', True) #MAKES THE WINDOW FULL SCREEN
- window.bind('<Escape>', lambda e: window.destroy()) #ALLOWS FOR ME TO CLOSE THE WINDOW
- Label (window, text= ' \n \n \n \n ', bg='black', fg='black', font=('times', 32)) .grid(row=0, column=2, sticky=W) #OUTPUTS MESSAGE IN BLACK IN ORDER TO COVER UP PREVIOUS MEESAGE IN WHITE SO EVENTS DONT WRITE OVER EACH OTHER
- #OUTPUTS THE DATE
- date2 = Label(window, font = ('times', 35, 'bold'), bg='black', fg='white') #DISPLAYS THE CLOCK
- date2.place(x=545, y=160) #POSITIONS THE CLOCK
- date()
- #OUTPUTS THE DAY OF THE WEEK:
- dayOfTheWeek = Label(window, font = ('times', 35, 'bold'), bg='black', fg='white') #DISPLAYS THE CLOCK
- dayOfTheWeek.place(x=590, y=100) #POSITIONS THE CLOCK
- day()
- #DISPLAYS THE TIME:
- clock = Label(window, font = ('times', 50, 'bold'), bg='black', fg='white') #DISPLAYS THE CLOCK
- clock.place(x=525, y=20) #POSITIONS THE CLOCK
- tick()
- Label (window, text='Reminders:', bg='black', fg='white', font=('times', 35)) .place(x=45, y=160) #OUTPUTS MESSAGE
- label_number_title = Label(window, text='Phone Numbers: Raj: 07--------- Aarti: 07--------- You: 07---------', fg='white', bg = 'black', font=('times', 30))
- label_number_title.place(x=200, y=833) #PLACES THE LABEL AT THE CORRESPONDING CO-ORDINATES
- #CALLING THE PROCEDURES:
- weather()
- calender()
- pic()
- remind()
- window.mainloop() #RUNS THE WINDOW
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement