def remove_notification(title): '''This function will remove a notification from the notifications json file''' with open('./json_files/notifications.json') as jfile: data = json.load(jfile) #getting the notificatios from the json file temp = data['notifications'] #the number of notifications in the file length = len(temp[0]) #getting the seen notifications file with open('./json_files/seen.json') as jfil: seen_data = json.load(jfil) #getting the notificatios from the json file seen = seen_data['notifications'] #looping through each notifications in the list for i in range(length): #then checking each notification title agaist the input title, #and if they are the same this will remove it if temp[0][i]["title"] == title: # appending data to seen notifications file seen.append(temp[0][i]) with open('./json_files/seen.json', 'w') as jfile: json.dump(seen_data, jfile, indent=4) log("notifications json file updated") log("notification for '" + title + "' has been removed") break
def get_covid(): '''This function gets the date for today and gets the key from teh confic json file and it then calls the api and returns the response''' #getting the users region from the config json file with open("./json_files/config.json", "r") as jfile: key = json.load(jfile) key = key["config"] area_name = key[4]['Area_location'] #concatonating the url fro teh api call, involving the location and the structure\ #which is, area name, date, new cases & new deaths complete_url = 'https://api.coronavirus.data.gov.uk/v1/data?filters=areaName='+ area_name +'&structure={"areaName":"areaName","date":"date",'\ +'"newCases":"newCasesByPublishDate","newDeaths":"newDeaths28DaysByPublishDate"}' #trying to get the data from the api call, if it can't #it will return failed so that the program can continue try: #making an api call with the requests module and the url response = requests.get(complete_url) report = response.json() #getting the data from the call report = report['data'] #logging that the data has been retrieved log("covid data retrieved -- " + str(requests.get(complete_url))) #returning the latest data from the report data return report[0] except: #logging and returning that the api calling has errored log("FAILED to get covid data from api" + str(requests.get(complete_url))) return "error getting covid info, api call error"
def write_json(data, alarm): '''This function opens the alarm json file and then adds the date passed to the function to the file''' with open('./json_files/alarms.json', 'w') as jfile: json.dump(data, jfile, indent=4) log("alarm for " + alarm + " has been added")
def write_json(data): '''This function opens the notification json file and then adds the data passed to the function to the file''' with open('./json_files/notifications.json', 'w') as jfile: json.dump(data, jfile, indent=4) log("notifications have been added to the json file")
def weathers(): '''This function does the api call to the website and it gets the api key from the config json file, then it returns the json file from the api call''' #setting the base url for the api call base_url = "http://api.openweathermap.org/data/2.5/weather?" #getting the users api key and their location (city name or town) from the config json file with open("./json_files/config.json", "r") as jfile: key = json.load(jfile) key = key["config"] api_key = key[0]['weatherkey'] city_name = key[3]['weather_city_or_town'] #adding this information to the base url so the api call can be made complete_url = base_url + "q=" + city_name + "&appid=" + api_key try: #making an api call with the requests module and the complete url response = requests.get(complete_url) weather_json = response.json() #logging that the weather has been retrieved if weather_json['cod'] == 200: log("weather retrieved -- " + str(requests.get(complete_url))) else: log("error getting the api data") log(requests.get(complete_url)) log(weather_json) #returning the weather data return weather_json except: #logging and returning that the api calling has errored log("FAILED to get Weather data from api" + str(requests.get(complete_url))) return [{'cod': '404', 'message': "FAILED couldn't get weather data"}]
def refresh(covid, articles, weather): '''This function will update the alarms with the latest covid,weather&news''' #getting all the alarms from the alarms json file with open("./json_files/alarms.json", "r") as jfile: alarm = json.load(jfile) alarmj = alarm["alarms"] #the length of the alarms (how many alarms ar set) length = len(alarmj) #a blank variable to use in the alarms call temp = '' #looping through each item in the alarm for i in range(length): #setting variables to tell the add alarm function if\ #there is a news and/or weather item in this alarm incl_news = alarmj[i]['pick_news'] incl_weather = alarmj[i]['pick_weather'] #setting the alarm title from the alarm in the json file alarm = alarmj[i]['title'] content = alarmj[i]['content'] #setting content to a string content = str(content) #the length of content content_length = len(content) #looping through the content to get the message that\ #the user entered for j in range(content_length): if content[j] == "'" and content[j + 1] == "'": ending = j break content = content[:(ending - 3)] #then removing the old alarm so there are no duplicates again remove_alarm(alarm, True) #logging that the alarm is updated log("alarm for " + alarm + " has been updated") #adding this to the alarms with the add alarm function\ #accoding to if the news and weather has been set if incl_news and incl_weather: #calling the add alarm function to add the updated alarm add_alarm(alarm, content, weather, articles, covid, incl_news, incl_weather) elif incl_weather: add_alarm(alarm, content, weather, temp, covid, incl_news, incl_weather) elif incl_news: add_alarm(alarm, content, temp, articles, covid, incl_news, incl_weather) else: add_alarm(alarm, content, temp, temp, covid, incl_news, incl_weather) return end()
def print_job_name(alarm, name, weather, article, covid): '''This function takes in input strings and then says them with pyttsx3''' #initiating the pyttsx3 engine = pyttsx3.init() alarm1 = alarm[11:] #adding the strings that have been passed to the function\ #to the say engine engine.say(alarm1) engine.say(name) engine.say(weather) engine.say(article) engine.say(covid) try: #saying the strings that are in the say engine engine.runAndWait() #logging that the alam has been said log("alarm for " + alarm + " has been said") ##removing the alarm as it has happened remove_alarm(alarm) except: log("FAILED speech run failed due to another item in the scheduler")
def news(): '''This function does the api call to the news website and it gets the api key from the config json file, then it returns the json file from the api call''' length = len(current_time_hhmm()) #looping through the time to find the middle (:) for i in range(length): if current_time_hhmm()[i] == ":": start = i + 1 #only getting the news from the api every 15 mins, or when the function is first called if int(current_time_hhmm()[start:]) % 15 == 0 or current_time_hhmm( )[start:] == '' or len(lst) == 0: if len(lst) == 0: lst.append('1') #setting the base url base_url = "https://newsapi.org/v2/top-headlines?" #getting the user key from the config json file with open("./json_files/config.json", "r") as jfile: key = json.load(jfile) key = key["config"] api_key = key[1]['newskey'] #adding these (key an country) to the base url to get the url for an api call complete_url = base_url + "country=gb&apiKey=" + api_key #trying to get the data from the api call, if it can't #it will return failed so that the program can continue try: #making an api call with the requests module and the complete url response = requests.get(complete_url) articles = response.json() #getting the articles from the api call response articles = articles["articles"] #logging that the articles have been retrieved log("articles retrieved -- " + str(requests.get(complete_url))) #returning the list of articles return articles except: #logging and returning that the api calling has errored log('FAILED to get news data from api' + str(requests.get(complete_url))) return [{'title': 'FAILED', 'content': "couldn't get news data"}] else: #opening the json file to read from it with open('./json_files/notifications.json') as jfile: data = json.load(jfile) #getting the notifications from the json file data = data['notifications'][0] log('notifications got from the json file') return data[2:]
def remove_alarm(title, status=False): '''This function opens the json file for the alarms and then it loops through the file until the title is the same and it removes that alarm''' with open('./json_files/alarms.json') as jfile: data = json.load(jfile) #getting the alarms from the json file temp = data['alarms'] #the number of alarms in the file length = len(temp) #looping through each alarm in the list for i in range(length): #then checkign each alarm title agaist the input title, #and if they are the same this will remove it if temp[i]["title"] == title: temp.pop(i) log("alarm for " + title + " has been removed") break #re-wrtiting the updated alarms to the json file with open('./json_files/alarms.json', 'w') as jfile: json.dump(data, jfile, indent=4) length = len(lst) if status: #looping through the scheduler list for i in range(length): try: #canceling the events in the list s.cancel(lst[i]) #logging that this has been done log('alarm ' + title + ' removed from scheduler') except: log('alarm' + title + 'could not be removed from the scheduler') #removing the item from the list lst.clear() if not status: refresh(get_covid(), news(), weathers())
def add_alarm(alarm, name, weather, article, covid, pick_news, pick_weather): '''This function adds the alarms inputed to the function to the json file of alarms and or adds it to the scheduler depends on conditions''' #running the scheduler s.run(blocking=False) #setting alarm1 to be the time part of the alarm title alarm1 = alarm[11:] if alarm1: #convert alarm_time to a delay current_time = current_time_hhmm() #working out the delay by subtracting the current time (in seconds)\ #from the time on the alarm (in seconds) delay = hhmm_to_seconds(alarm1) - hhmm_to_seconds(current_time) #setting a new name variable to append to what is in the input\ #and still keep the input var new_name = name #The conditions on whether to manipulate the weather,news & covid\ #depending on whether they were inputted if weather != '' and weather["cod"] == 200: #setting weath to the main attributes of the weather input weath = weather["main"] #getting the tempurature current_temp = weath["temp"] #getting the pressure current_press = weath["pressure"] #getting the humidity current_humid = weath["humidity"] #setting weath to the weather attribute of the weather input weath = weather["weather"] #getting the description from the weather input (from weath) weather_desc = weath[0]["description"] #gettign the wind speed weath = weather["wind"] #concatonating all the variables gathered on weather into one string with\ #more descriptions of them weather = "The temperature outside is "+str(int(current_temp - 273.15))\ + "degrees centigrade; The atmospheric pressure is "\ + str(current_press) + "hectopascals; The humidity is " + str(current_humid) +\ "percent; The wind speed is "+str(weath['speed'])+\ "metres per second; And it is "+str(weather_desc) #adding this to the newname variable new_name = str(new_name) + ". '''''''' " + str(weather) #inputting to the alarm that there is an error if false weather data is added to an alarm elif weather != '' and weather["cod"] != 200: wdic = {'title': weather["cod"], 'content': weather['message']} new_name = str(new_name) + ". '''''''' " + str(wdic) if article != '': #getting the title from the news input article = article[0]['title'] article = str('The top news story is: ') + str(article) #adding this information plus a description to the newname variable new_name = str(new_name) + ". '''''''' " + str(article) if covid != '': covid = 'The local coronavirus infection rates are: ' + str(covid) #adding the information on covid to the newname variable new_name = str(new_name) + ". ''''''' " + str(covid) #setting the details abotu the news alarm from the inputs new_alarm = {"title": alarm, "content": new_name, "pick_news": pick_news,\ "pick_weather": pick_weather} #opening the alarm json file and getting all the alarms from it with open('./json_files/alarms.json') as jfile: data = json.load(jfile) temp = data['alarms'] in_alarms = False if len(temp) != 0: #looping though the alarms json if it isnt empty for i in temp: if i['title'] == alarm: #if the alarm exists that is being added then in alarms is true if not its false in_alarms = True break #appending the json file if that alarm doesnt exist if not in_alarms: # appending data to alarms temp.append(new_alarm) #calling the write function to add the new alarms to the json file write_json(data, alarm) else: log('cannot make alarm as there is already an alarm for this time') return end() #saying the event if it is set for the time now\ #and if the date on the alarm is the same as todays date if alarm[:10] == current_date() and int(delay) == 0: print_job_name(alarm, name, weather, article, covid) #Not adding the alarm if it is set in the past elif alarm[:10] == current_date() and int(delay) < 0: log("alarm " + alarm + " is set in the past") remove_alarm(alarm, True) #only adding an item to the scheduler if it has less than 60 seconds\ #and if the date on the alarm is the same as todays date elif alarm[:10] == current_date() and 0 < int(delay) < 61: lst.append( s.enter(int(delay), 1, print_job_name, [ alarm, name, weather, article, covid, ])) #logging that the alarm has been added to the scheduler log("alarm " + alarm + " added to the scheduler") return end() #returning end if there is nothing to do return end()
def org_func(covid, weather, articles): '''This function takes in the 3 dictionsaries covid, weather & articles and then it formats them and returns them in one list''' length = len(current_time_hhmm()) for i in range(length): if current_time_hhmm()[i] == ":": start = i + 1 #refreshing the seen file so it doesn't contain irrelevent info, and because by ever hour\ #normally all of the nes has been updated and the data in the seen file is different to the\ #new nes anyway if current_time_hhmm()[start:] == '': with open('./json_files/seen.json', 'w') as jfile: json.dump({'notifications': []}, jfile, indent=4) #this wil update the notifications collumn every 15 mins or when the function is first called if int(current_time_hhmm()[start:]) % 15 == 0 or current_time_hhmm( )[start:] == '' or len(lst) == 0: #updating the list if it is the first time the function is called if len(lst) == 0: lst.append('1') length = len(articles) i = 0 #this will loop through every item (article) in articles #if the api call didn't fail if articles[0]['title'] != 'FAILED': while i < length: #adding the url of the website in the article to the content variable as\ #markup so it can be displayed on the website (with html) content = Markup( ("<a href='%s'target='_blank'>click_here</a>" % (articles[i]['url']))) #then adding this to the content of the spcific article articles[i]['content'] = str( articles[i]['description']) + ' ------ ' + content i += 1 #setting the covid input to be added as a dictionary dic = { 'title': 'Daily local covid infection rates', 'content': str(covid), 'url': '' } #adding this dictionary to articles articles.insert(0, dic) #chekcing if there has been weather data inputted and that there hasn't been an error if weather != [] and weather["cod"] == 200: #setting weath to the main attributes of the weather input weath = weather["main"] #getting the tempurature current_temp = weath["temp"] #getting the pressure current_press = weath["pressure"] #getting the humidity current_humid = weath["humidity"] #setting weath to the weather attribute of the weather input weath = weather["weather"] #getting the description from the weather input (from weath) weather_desc = weath[0]["description"] #getting the wind speed weath = weather["wind"] #concatonating all the variables gathered on weather into one string with\ #more descriptions of them description = "The temperature outside is "+str(int(current_temp - 273.15))\ + " degrees centigrade; The atmospheric pressure is "\ + str(current_press) + "hPa; The humidity is " + str(current_humid) +\ "%; The wind speed is "+str(weath['speed'])+"m/s; And it is "+\ str(weather_desc) #putting this description into a dictionary with the other informaiont about weather wdic = { 'title': 'Weather in Exeter', 'content': description, 'url': '' } #adding this dictionary to articles articles.insert(1, wdic) #adding to articles that there has been an error with the api call elif weather != [] and weather["cod"] != 200: wdic = { 'title': weather["cod"], 'content': weather['message'], 'url': '' } articles.insert(1, wdic) #logging that the inputs have been organised into notifications log("notifications organised") data = {'notifications': [articles]} #calling the write function to add the new notifications to the json file write_json(data) #opening the json file to read from it with open('./json_files/notifications.json') as jfile: data = json.load(jfile) #getting the notifications from the json file data = data['notifications'][0] log('notifications from json file returned') #looping through the json file and adding the urls as links length = len(data) if data[2]['title'] != 'FAILED': for i in range(length): if data[i]['url']: #adding the url of the website in the article to the content variable as\ #markup so it can be displayed on the website (with html) content = Markup( ("<a href='%s'target='_blank'>click_here</a>" % (data[i]['url']))) #then adding this to the content of the spcific article data[i]['content'] = str( data[i]['description']) + ' ------ ' + content notifications = [] #getting the seen notifications file with open('./json_files/seen.json') as jfil: seen = json.load(jfil) #getting the notificatios from the json file seen = seen['notifications'] for i in data: if i not in seen: notifications.append(i) #returning the notifications in the json file return notifications
def logg(): '''This logs when the python service is closed''' log('-------FINISHED-------')
def rootindex(): '''This adds, started, to the logfile and redirects the user to the index page''' log('-------STARTED-------') return redirect("/index")