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 controller():
    """Controlls what happens, returns the alarm and the news notifications and so forth."""
    alarm_item = request.args.get("alarm_item")
    if alarm_item != None:
        for alarm in alarms:
            if alarm['title'] == alarm_item:
                alarms.remove(alarm)

    s.run(blocking=False)
    alarm_time = request.args.get("alarm")
    news = get_top_headlines()
    if alarm_time:
        #convert alarm_time to a delay
        alarm_hhmm = alarm_time[-5:-3] + ':' + alarm_time[-2:]
        delay = hhmm_to_seconds(alarm_hhmm) - hhmm_to_seconds(current_time_hhmm())
        weather_input = ""
        news_input = ""
        if request.args.get("weather") != None and request.args.get("news") != None:
            weather_input = get_weather()
            news_input = get_news_briefing()
            setalarm("It is: " + alarm_time + " and the weather is: "  + weather_input + " Here are your covid news updates: " + news_input)
        elif request.args.get("weather") != None:
            weather_input = get_weather()
            setalarm("It is: " + alarm_time + " and the weather is " + weather_input + " Here are your covid news updates: " + news_input)
        elif request.args.get("news") != None:
            news_input = get_news_briefing()
            setalarm(alarm_time + " " + weather_input + news_input)
        else:
            setalarm(alarm_time)
        s.enter(int(delay), 1, announce, (alarms[-1]['content'],))

    return render_template('index.html', title='Daily update', notifications=news, image='alarm-meme.jpg', alarms= alarms)
Пример #3
0
def controller():
    """ Function runs the alarm

    This function is what is called every time the page refreshes and is the homepage
    It holds the majority of the functionality of the alarm, with most larger modules running here.
    Function contains functions that schedules todays alarms and notifications. Sets alarms and removes
    notifications and alarms

    """
    alarm_time = request.args.get("alarm")
    s.run(
        blocking=False
    )  #allows alarms to be scheduled without freezing the interface if a scheduled event is running
    logging.info('Page refreshed, running on controller')
    if current_time_hhmm(
    ) == '00:00':  #set new alarms and notifications at midnight
        set_todays_alarms()
        automatic_notifications_remover_appender()
    if alarm_time:  #if an alarm is scheduled
        set_alarm()
    if request.args.get(
            "alarm_item"
    ):  #if an alarm is removed by the user (x in the corner clicked)
        remove_alarm()
    if request.args.get(
            "notif"
    ):  #if a notification is removed by the user (x in the corner clicked)
        remove_notification()
    return render_template('index.html',
                           title='Daily update',
                           alarms=alarms,
                           notifications=notifications,
                           image='meme.jpg')  #requires
Пример #4
0
def regular_actions(hour: bool =False, day: bool =False, first_time: bool =False) -> None:
    '''
    Parameters
    ----------
    hour : bool, optional
        Triggers the make_notifications function and schedules it to be done
        again in an hour. The default is False.
    day : bool, optional
        Triggers the load_alarms_from_log function and schedules it to be done
        again in a day. The default is False.
    first_time : bool, optional
        Trigers both load_alarms_from_log and make_notifications to be run. It
        schedueles them to be run again at 00:02 and the begining of the hour
        respectively. The default is False.

    Returns
    -------
    None
        This module is for ensuring that the notifications are kept upto date
        regularly and that every day the relevant alarms are loaded from the
        log file. It also has a first time flag to complete both these methods
        on startup.'''
    if first_time:
        make_notifications()
        load_alarms_from_log()
        delay = time_conversions.hhmm_to_seconds(str(int(time.strftime('%H'))+1) + ':01') - \
            time_conversions.hhmm_to_seconds(time_conversions.current_time_hhmm()) - \
            int(time.strftime('%S'))
        scheduler.enter(float(delay), 1, regular_actions, (True,))
        delay = (time_conversions.hhmm_to_seconds('23:59') - \
            time_conversions.hhmm_to_seconds(time_conversions.current_time_hhmm()) - \
            int(time.strftime('%S'))) + 180
        scheduler.enter(float(delay), 1, regular_actions, (False, True,))
        logging.info(
    'make_notifications and load_alarms_from_log have been run for the first time and rescheduled.')
    elif hour:
        make_notifications()
        scheduler.enter(float(reload_notifications), 1, regular_actions, (True,))
        logging.info('make_notifications has been run and rescheduled')
    elif day:
        load_alarms_from_log()
        scheduler.enter(float(86400), 1, regular_actions, (False, True))
        logging.info('load_alarms_from_log has been run and rescheduled')
Пример #5
0
def set_an_alarm(alarm_time: str, alarm_title: str, read_news: str, read_weather: str) -> None:
    '''
    Parameters
    ----------
    alarm_time : str
        The time the alarm should go off. FORMAT: "HH:MM".
    alarm_title : str
        The title of the alarm passed through from the HTML form.
    read_news : str
        Is equal to 'news' if the news should be read with the alarm.
    read_weather : str
        Is equal to 'weather' if the weather should be read with the alarm.

    Returns
    -------
    None
        This function creates the user-friendly tile that is displayed in the
        browser and adds it to the ALARMS list. It checks if the alarm is
        in the past and if it is ignors the request. If the alarm is the same
        day in the future it schedules and logs it. If the alarm is in the
        future and not on the current day it only logs it so that it can be
        loaded in and scheduled after midnight on the relevant day.
    '''
    global ALARMS
    global NOTIFICATIONS
    content = 'This alarm will:<br />Make an announcement'
    title = alarm_time[:10] + ' - ' + alarm_time[-5:] + ' - ' + alarm_title
    # Check alarm is today and in the future
    if date(int(alarm_time[:4]), int(alarm_time[5:7]), int(alarm_time[8:10])) > date.today():
        logging.critical([alarm_time, alarm_title, read_news, read_weather])
        if read_news:
            content += '<br />Read the headlines'
        if read_weather:
            content += '<br />Read the weather'
        ALARMS.append({'title':title, \
                       'content':Markup(content), \
                       'news':read_news, \
                       'weather':read_weather, \
                       'event':None
                       })
        logging.info(
            'Alarm %s has been logged for the future and added to ALARMS.', title)
    elif datetime.datetime(int(alarm_time[:4]), int(alarm_time[5:7]), \
                           int(alarm_time[8:10]), int(alarm_time[11:13]), \
                           int(alarm_time[14:])) > datetime.datetime.now():
        # Convert alarm_time to a delay
        alarm_hhmm = alarm_time[-5:-3] + ':' + alarm_time[-2:]
        delay = time_conversions.hhmm_to_seconds(alarm_hhmm) - \
            time_conversions.hhmm_to_seconds(time_conversions.current_time_hhmm()) - \
            int(time.strftime('%S'))
        if read_news:
            content += '<br />Read the headlines'
        if read_weather:
            content += '<br />Read the weather'
        logging.critical([alarm_time, alarm_title, read_news, read_weather])
        ALARMS.append({'title':title, \
                       'content':Markup(content), \
                       'news':read_news, \
                       'weather':read_weather, \
                       'event':scheduler.enter(float(delay), 1, \
                                               say_and_remove, \
                                               (title, alarm_title)) })
        logging.info(
            'Alarm %s has been logged, scheduled and added to ALARMS.', title)
    else:
        NOTIFICATIONS.insert(0, {'title':'ALARM TIME NOT POSSIBLE', \
                       'content': 'The date and time you choese must be in the future.'})
        logging.debug('The user tried to set an alarm in the future %s', title)
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
Пример #8
0
def set_alarm():
    """This function sets alarms

    It first checks whether the alarm has been set in the past. Which will cause it to log the alarm as in the past
    but will not append it.
    It then sets the alarm if it is set for today and if it is not it will add it to a list. Each day this list is checked
    and if the date on the alarm matches the date of the current day the alarm will be set for that day.
    When an alarm is set for today or added to a list to be set in the future, it will add an alarm on the left hand side of
    the interface with the title and the time that it will trigger.

    """
    alarm_time = request.args.get("alarm")
    alarm_hhmm = alarm_time[-5:-3] + ':' + alarm_time[-2:]
    if full_date.year > int(alarm_time[0:4]) or full_date.month > int(
            alarm_time[5:7]) or full_date.day > int(alarm_time[8:10]):
        return logging.info('Alarm is in the past')
    if full_date.year == int(alarm_time[0:4]) and full_date.month == int(
            alarm_time[5:7]) and full_date.day == int(alarm_time[8:10]):
        if hhmm_to_seconds(alarm_hhmm) < hhmm_to_seconds(current_time_hhmm()):
            logging.info('Alarm is in the past')
            return render_template('index.html',
                                   title='Daily update',
                                   alarms=alarms,
                                   notifications=notifications,
                                   image='meme.jpg')
        delay = hhmm_to_seconds(alarm_hhmm) - hhmm_to_seconds(
            current_time_hhmm())
        date = alarm_time[0:10]
        events.append({
            "date": date,
            "delay": delay,
            "event_title": request.args.get("two"),
            "time": alarm_hhmm
        })
        alarms.append({
            "title":
            request.args.get("two"),
            "content":
            'Will be updated on announcement ( ' + alarm_time[0:10] + ' ' +
            alarm_time[12:] + ' )in order to provide relevant information'
        })  #changed from alarm content
        events_list.append({
            "title":
            request.args.get("two"),
            "content":
            s.enter(int(delay), 1, alarm_runner,
                    (alarm_content(), request.args.get("two")))
        })
        logging.info('Alarm set for today at ' + alarm_time)
        return render_template('index.html',
                               title='Daily update',
                               alarms=alarms,
                               notifications=notifications,
                               image='meme.jpg')
    delay = hhmm_to_seconds(alarm_hhmm) - hhmm_to_seconds(current_time_hhmm())
    date = alarm_time[0:10]
    events.append({
        "date": date,
        "delay": delay,
        "title": request.args.get("two"),
        "time": alarm_hhmm
    })
    alarms.append({
        "title":
        request.args.get("two"),
        "content":
        'Will be updated on announcement ( ' + alarm_time[0:10] + ' ' +
        alarm_time[12:] + ' )in order to provide relevant information'
    })
    logging.info('Alarm set for ' + alarm_time +
                 'future date, will be scheduled on the date')
    return render_template('index.html',
                           title='Daily update',
                           alarms=alarms,
                           notifications=notifications,
                           image='meme.jpg')