Exemplo n.º 1
0
def extract_datetime(text, anchorDate=None, lang="en-us", default_time=None):
    """
    Extracts date and time information from a sentence.  Parses many of the
    common ways that humans express dates and times, including relative dates
    like "5 days from today", "tomorrow', and "Tuesday".

    Vague terminology are given arbitrary values, like:
        - morning = 8 AM
        - afternoon = 3 PM
        - evening = 7 PM

    If a time isn't supplied or implied, the function defaults to 12 AM

    Args:
        text (str): the text to be interpreted
        anchorDate (:obj:`datetime`, optional): the date to be used for
            relative dating (for example, what does "tomorrow" mean?).
            Defaults to the current local date/time.
        lang (string): the BCP-47 code for the language to use
        default_time (datetime.time): time to use if none was found in
            the input string.

    Returns:
        [:obj:`datetime`, :obj:`str`]: 'datetime' is the extracted date
            as a datetime object in the user's local timezone.
            'leftover_string' is the original phrase with all date and time
            related keywords stripped out. See examples for further
            clarification

            Returns 'None' if no date or time related text is found.

    Examples:

        >>> extract_datetime(
        ... "What is the weather like the day after tomorrow?",
        ... datetime(2017, 06, 30, 00, 00)
        ... )
        [datetime.datetime(2017, 7, 2, 0, 0), 'what is weather like']

        >>> extract_datetime(
        ... "Set up an appointment 2 weeks from Sunday at 5 pm",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        [datetime.datetime(2016, 3, 6, 17, 0), 'set up appointment']

        >>> extract_datetime(
        ... "Set up an appointment",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        None
    """

    lang_lower = str(lang).lower()

    if not anchorDate:
        anchorDate = now_local()

    if lang_lower.startswith("en"):
        return extract_datetime_en(text, anchorDate, default_time)
    elif lang_lower.startswith("es"):
        return extract_datetime_es(text, anchorDate, default_time)
    elif lang_lower.startswith("pt"):
        return extract_datetime_pt(text, anchorDate, default_time)
    elif lang_lower.startswith("it"):
        return extract_datetime_it(text, anchorDate, default_time)
    elif lang_lower.startswith("fr"):
        return extract_datetime_fr(text, anchorDate, default_time)
    elif lang_lower.startswith("sv"):
        return extract_datetime_sv(text, anchorDate, default_time)
    elif lang_lower.startswith("de"):
        return extract_datetime_de(text, anchorDate, default_time)
    # TODO: extract_datetime for other languages
    LOG.warning('Language "{}" not recognized! Please make sure your '
                'language is one of the following: '
                'en, es, pt, it, fr, sv, de.'.format(lang_lower))
    return text
Exemplo n.º 2
0
def extract_datetime(text, anchorDate=None, lang=None, default_time=None):
    """
    Extracts date and time information from a sentence.  Parses many of the
    common ways that humans express dates and times, including relative dates
    like "5 days from today", "tomorrow', and "Tuesday".

    Vague terminology are given arbitrary values, like:
        - morning = 8 AM
        - afternoon = 3 PM
        - evening = 7 PM

    If a time isn't supplied or implied, the function defaults to 12 AM

    Args:
        text (str): the text to be interpreted
        anchorDate (:obj:`datetime`, optional): the date to be used for
            relative dating (for example, what does "tomorrow" mean?).
            Defaults to the current local date/time.
        lang (str): the BCP-47 code for the language to use, None uses default
        default_time (datetime.time): time to use if none was found in
            the input string.

    Returns:
        [:obj:`datetime`, :obj:`str`]: 'datetime' is the extracted date
            as a datetime object in the user's local timezone.
            'leftover_string' is the original phrase with all date and time
            related keywords stripped out. See examples for further
            clarification

            Returns 'None' if no date or time related text is found.

    Examples:

        >>> extract_datetime(
        ... "What is the weather like the day after tomorrow?",
        ... datetime(2017, 06, 30, 00, 00)
        ... )
        [datetime.datetime(2017, 7, 2, 0, 0), 'what is weather like']

        >>> extract_datetime(
        ... "Set up an appointment 2 weeks from Sunday at 5 pm",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        [datetime.datetime(2016, 3, 6, 17, 0), 'set up appointment']

        >>> extract_datetime(
        ... "Set up an appointment",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        None
    """

    lang_code = get_primary_lang_code(lang)

    if not anchorDate:
        anchorDate = now_local()

    if lang_code == "en":
        return extract_datetime_en(text, anchorDate, default_time)
    elif lang_code == "es":
        return extract_datetime_es(text, anchorDate, default_time)
    elif lang_code == "pt":
        return extract_datetime_pt(text, anchorDate, default_time)
    elif lang_code == "it":
        return extract_datetime_it(text, anchorDate, default_time)
    elif lang_code == "fr":
        return extract_datetime_fr(text, anchorDate, default_time)
    elif lang_code == "sv":
        return extract_datetime_sv(text, anchorDate, default_time)
    elif lang_code == "de":
        return extract_datetime_de(text, anchorDate, default_time)
    elif lang_code == "da":
        return extract_datetime_da(text, anchorDate, default_time)
    elif lang_code == "ar":
        return extract_datetime_ar(text, anchorDate, default_time)
    # TODO: extract_datetime for other languages
    _log_unsupported_language(lang_code,
                              ['en', 'es', 'pt', 'it', 'fr', 'sv', 'de', 'da'])
    return text
Exemplo n.º 3
0
    def handle_generate_intent(self, message):
        # month = message.data.get("Month")
        # self.log.error(month)

        # For test.
        month = "this"

        if not month:
            self.speak_dialog("error.input.mh")
            return

        category = self.get_response("category.mh")

        if not category or category not in [
                "pressure", "diabetes", "pain", "temperature", "heartbeat"
        ]:
            self.speak_dialog("error.input.mh")
            return

        person = self.get_response("person.mh")
        person = "" if not person else person

        current_datetime = now_local()

        # Multi languages support should be implemented here.
        if month == "this" or month == "current":
            to_datetime = current_datetime

        elif month == "last" or month == "previous":
            to_datetime = current_datetime.replace(
                day=1, hour=23, minute=59, second=59,
                microsecond=0) - timedelta(days=1)

        from_datetime = to_datetime.replace(day=1,
                                            hour=0,
                                            minute=0,
                                            second=0,
                                            microsecond=0)

        health_data_list = self.get_data(from_datetime, to_datetime, category,
                                         person)

        health_data = []

        for data in health_data_list:
            health_data.append({
                'Datetime':
                data[0].strftime("%m/%d/%Y %H:%M:%S"),
                'Category':
                data[1],
                'Value':
                data[2],
                'Parameter':
                data[3],
                'Person':
                data[4]
            })

        table = json2html.convert(json=health_data)

        content = """
        <!DOCTYPE html><html><head><style>table{font-family:arial,sans-serif;
        border-collapse:collapse;width:100%;}td,th{border:1px solid #dddddd;
        text-align:left;padding:8px;}tr:nth-child(even)
        {background-color: #dddddd;}</style></head><body>"""

        content = """
        {0}<h2>Health Data: {1} to {2}</h2>
        {3}</body></html>""".format(
            content, from_datetime.strftime("%m/%d/%Y %H:%M:%S"),
            to_datetime.strftime("%m/%d/%Y %H:%M:%S"), table)

        # self.send_email(
        #             "Health Report - {0}".format(category.upper()),
        #             content)

        # For test.
        message = Mail(from_email="Mycroft Health <*****@*****.**>",
                       to_emails="*****@*****.**",
                       subject="Mycroft Health Report - {0}".format(
                           category.upper()),
                       html_content=content)

        # Please provide your own Api key for testing as it's not wise to
        # expose Api key in public.

        api_key = "<your sendgrid API key>"

        try:
            sg = SendGridAPIClient(api_key)
            _ = sg.send(message)

        except Exception:
            pass
Exemplo n.º 4
0
    def handle_skill_study(self, message):

        # Give a welcome message to the user
        self.speak_dialog('skill.welcome')
        participantnumber = self.get_response('skill.participant.number')

        # Get the tasks the user wants to accomplish
        tasks = []
        task1 = self.get_response('tasks.task1')
        self.speak_dialog('tasks.task1.confirmation', data={"task1": task1})
        tasks.append(task1)

        another_task = self.ask_yesno('tasks.another.task')
        while another_task != 'yes' and another_task != 'no':
            self.speak_dialog('skill.task.could.not.understand')
            another_task = self.ask_yesno('tasks.another.task')
        if another_task == "yes":
            task2 = self.get_response('tasks.task2')
            tasks.append(task2)
        elif another_task == "no":
            self.speak_dialog('tasks.moveon')

        last_task = self.ask_yesno('tasks.last.task')
        while last_task != 'yes' and last_task != 'no':
            self.speak_dialog('skill.last.task.could.not.understand')
            last_task = self.ask_yesno('tasks.last.task')
        if last_task == "yes":
            task3 = self.get_response('tasks.task3')
            tasks.append(task3)
        elif last_task == "no":
            self.speak_dialog('tasks.moveon')

        if len(tasks) == 1:
            number_of_tasks = "1 task"
        if len(tasks) > 1:
            number_of_tasks = "{} tasks".format(len(tasks))

        self.speak_dialog('tasks.confirmation',
                          data={"number_of_tasks": number_of_tasks})

        # Get the amount of blocks from the user
        # a selection is used, to minimize pronunciation errors. This way, the answer is compared to the options and the option that matches the answer the most is chosen.
        # For example, if mycroft thinks a user says 'free brooks', he will pick three blocks as answer.

        self.speak_dialog('blocks.amount.of.blocks')
        blocks = extract_number(
            self.ask_selection(['one block', 'two blocks', 'three blocks'],
                               'blocks.selection'))
        while not blocks:
            self.speak_dialog('skill.blocks.could.not.understand')
            blocks = extract_number(
                self.ask_selection(['one block', 'two blocks', 'three blocks'],
                                   'skill.blocks.could.not.understand'))

        # If the user selects one block, Mycroft responds with the singular "block"
        if blocks == 1:
            amount_of_blocks = "1 block"

        # If the user selects multiple blocks, Mycroft responds with the plural "blocks"
        if blocks > 1:
            amount_of_blocks = "{} blocks".format(str(blocks))

        # Get the current time to calculate the time when the user will be done in the future
        now = now_local()
        currenttime = now.strftime("%H:%M")

        # Calculate the time when the user is done based on the amount of blocks selected
        # Each block is 25 minutes and each break is 5 minutes

        minutes = blocks * 25 + (blocks - 1) * 5
        futuretime = now + timedelta(minutes=minutes)
        futuretime = futuretime.strftime("%H:%M")

        # Respond to the user with the amount of blocks they have chosen, what the curren time is
        # and when their study session will be finished
        self.speak_dialog('blocks.confirmation',
                          data={
                              'currenttime': currenttime,
                              'amount_of_blocks': amount_of_blocks,
                              'futuretime': futuretime
                          })

        # The time.sleep() function takes an input of seconds
        # If you want the code to sleep for several minutes you should multiply the values with 60
        # Currently everythting is in second for debugging purposes
        for i in range(blocks):
            time.sleep(25)
            if i < blocks - 1:
                self.speak_dialog('study.break.begin')
                time.sleep(5)
                self.speak_dialog('study.break.end')
            if i == blocks - 1:
                break
        self.speak_dialog('study.end')
Exemplo n.º 5
0
    def handle_query_date(self, message, response_type="simple"):
        utt = message.data.get('utterance', "").lower()
        try:
            extract = extract_datetime(utt)
        except Exception:
            self.speak_dialog('date.not.found')
            return
        day = extract[0] if extract else now_local()

        # check if a Holiday was requested, e.g. "What day is Christmas?"
        year = extract_number(utt)
        if not year or year < 1500 or year > 3000:  # filter out non-years
            year = day.year
        all_holidays = {}
        # TODO: How to pick a location for holidays?
        for st in holidays.US.STATES:
            holiday_dict = holidays.US(years=[year], state=st)
            for d, name in holiday_dict.items():
                if name not in all_holidays:
                    all_holidays[name] = d
        for name in all_holidays:
            d = all_holidays[name]
            # Uncomment to display all holidays in the database
            # self.log.info("Day, name: " +str(d) + " " + str(name))
            if name.replace(" Day", "").lower() in utt:
                day = d
                break

        location = self._extract_location(utt)
        today = to_local(now_utc())
        if location:
            # TODO: Timezone math!
            if (day.year == today.year and day.month == today.month
                    and day.day == today.day):
                day = now_utc()  # for questions ~ "what is the day in sydney"
            day = self.get_local_datetime(location, dtUTC=day)
        if not day:
            return  # failed in timezone lookup

        speak_date = nice_date(day, lang=self.lang)
        # speak it
        if response_type == "simple":
            self.speak_dialog("date", {"date": speak_date})
        elif response_type == "relative":
            # remove time data to get clean dates
            day_date = day.replace(hour=0, minute=0, second=0, microsecond=0)
            today_date = today.replace(hour=0,
                                       minute=0,
                                       second=0,
                                       microsecond=0)
            num_days = (day_date - today_date).days
            if num_days >= 0:
                speak_num_days = nice_duration(num_days * 86400)
                self.speak_dialog("date.relative.future", {
                    "date": speak_date,
                    "num_days": speak_num_days
                })
            else:
                # if in the past, make positive before getting duration
                speak_num_days = nice_duration(num_days * -86400)
                self.speak_dialog("date.relative.past", {
                    "date": speak_date,
                    "num_days": speak_num_days
                })

        # and briefly show the date
        self.answering_query = True
        self.show_date(location, day=day)
        time.sleep(10)
        mycroft.audio.wait_while_speaking()
        if self.platform == "mycroft_mark_1":
            self.enclosure.mouth_reset()
            self.enclosure.activate_mouth_events()
        self.answering_query = False
        self.displayed_time = None
Exemplo n.º 6
0
def extract_datetime(text, anchorDate=None, lang="en-us", default_time=None):
    """
    Extracts date and time information from a sentence.  Parses many of the
    common ways that humans express dates and times, including relative dates
    like "5 days from today", "tomorrow', and "Tuesday".

    Vague terminology are given arbitrary values, like:
        - morning = 8 AM
        - afternoon = 3 PM
        - evening = 7 PM

    If a time isn't supplied or implied, the function defaults to 12 AM

    Args:
        text (str): the text to be interpreted
        anchorDate (:obj:`datetime`, optional): the date to be used for
            relative dating (for example, what does "tomorrow" mean?).
            Defaults to the current local date/time.
        lang (string): the BCP-47 code for the language to use
        default_time (datetime.time): time to use if none was found in
            the input string.

    Returns:
        [:obj:`datetime`, :obj:`str`]: 'datetime' is the extracted date
            as a datetime object in the user's local timezone.
            'leftover_string' is the original phrase with all date and time
            related keywords stripped out. See examples for further
            clarification

            Returns 'None' if no date or time related text is found.

    Examples:

        >>> extract_datetime(
        ... "What is the weather like the day after tomorrow?",
        ... datetime(2017, 06, 30, 00, 00)
        ... )
        [datetime.datetime(2017, 7, 2, 0, 0), 'what is weather like']

        >>> extract_datetime(
        ... "Set up an appointment 2 weeks from Sunday at 5 pm",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        [datetime.datetime(2016, 3, 6, 17, 0), 'set up appointment']

        >>> extract_datetime(
        ... "Set up an appointment",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        None
    """

    lang_lower = str(lang).lower()

    if not anchorDate:
        anchorDate = now_local()

    if lang_lower.startswith("en"):
        return extract_datetime_en(text, anchorDate, default_time)
    elif lang_lower.startswith("es"):
        return extract_datetime_es(text, anchorDate, default_time)
    elif lang_lower.startswith("pt"):
        return extract_datetime_pt(text, anchorDate, default_time)
    elif lang_lower.startswith("it"):
        return extract_datetime_it(text, anchorDate, default_time)
    elif lang_lower.startswith("fr"):
        return extract_datetime_fr(text, anchorDate, default_time)
    elif lang_lower.startswith("sv"):
        return extract_datetime_sv(text, anchorDate, default_time)
    elif lang_lower.startswith("de"):
        return extract_datetime_de(text, anchorDate, default_time)
    # TODO: extract_datetime for other languages
    LOG.warning('Language "{}" not recognized! Please make sure your '
                'language is one of the following: '
                'en, es, pt, it, fr, sv, de.'.format(lang_lower))
    return text
Exemplo n.º 7
0
def extract_datetime(text, anchorDate=None, lang=None, default_time=None):
    """
    Extracts date and time information from a sentence.  Parses many of the
    common ways that humans express dates and times, including relative dates
    like "5 days from today", "tomorrow', and "Tuesday".

    Vague terminology are given arbitrary values, like:
        - morning = 8 AM
        - afternoon = 3 PM
        - evening = 7 PM

    If a time isn't supplied or implied, the function defaults to 12 AM

    Args:
        text (str): the text to be interpreted
        anchorDate (:obj:`datetime`, optional): the date to be used for
            relative dating (for example, what does "tomorrow" mean?).
            Defaults to the current local date/time.
        lang (str): the BCP-47 code for the language to use, None uses default
        default_time (datetime.time): time to use if none was found in
            the input string.

    Returns:
        [:obj:`datetime`, :obj:`str`]: 'datetime' is the extracted date
            as a datetime object in the user's local timezone.
            'leftover_string' is the original phrase with all date and time
            related keywords stripped out. See examples for further
            clarification

            Returns 'None' if no date or time related text is found.

    Examples:

        >>> extract_datetime(
        ... "What is the weather like the day after tomorrow?",
        ... datetime(2017, 06, 30, 00, 00)
        ... )
        [datetime.datetime(2017, 7, 2, 0, 0), 'what is weather like']

        >>> extract_datetime(
        ... "Set up an appointment 2 weeks from Sunday at 5 pm",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        [datetime.datetime(2016, 3, 6, 17, 0), 'set up appointment']

        >>> extract_datetime(
        ... "Set up an appointment",
        ... datetime(2016, 02, 19, 00, 00)
        ... )
        None
    """

    lang_code = get_primary_lang_code(lang)

    if not anchorDate:
        anchorDate = now_local()

    if lang_code == "en":
        return extract_datetime_en(text, anchorDate, default_time)
    elif lang_code == "es":
        return extract_datetime_es(text, anchorDate, default_time)
    elif lang_code == "pt":
        return extract_datetime_pt(text, anchorDate, default_time)
    elif lang_code == "it":
        return extract_datetime_it(text, anchorDate, default_time)
    elif lang_code == "fr":
        return extract_datetime_fr(text, anchorDate, default_time)
    elif lang_code == "sv":
        return extract_datetime_sv(text, anchorDate, default_time)
    elif lang_code == "de":
        return extract_datetime_de(text, anchorDate, default_time)
    elif lang_code == "da":
        return extract_datetime_da(text, anchorDate, default_time)
    # TODO: extract_datetime for other languages
    _log_unsupported_language(lang_code,
                              ['en', 'es', 'pt', 'it', 'fr', 'sv', 'de', 'da'])
    return text
Exemplo n.º 8
0
 def remaining_time(self):
     return self.settings["duration"] - (now_local() -
                                         self.start_time).total_seconds()
Exemplo n.º 9
0
    def handle_start_timer(self, message):
        """ Common handler for start_timer intents
        """
        utt = message.data["utterance"]
        #~~ GET TIMER DURATION
        secs, utt_remaining = self._extract_duration(utt)
        if secs and secs == 1:  # prevent "set one timer" doing 1 sec timer
            utt_remaining = message.data["utterance"]

        if secs == None:  # no duration found, request from user
            req_duration = self.get_response('ask.how.long')
            secs, _ = self._extract_duration(req_duration)
            if secs is None:
                return  # user cancelled

        #~~ GET TIMER NAME
        if utt_remaining is not None and len(utt_remaining) > 0:
            timer_name = self._get_timer_name(utt_remaining)
            if timer_name:
                if self._check_duplicate_timer_name(timer_name):
                    return  # make another timer with a different name
        else:
            timer_name = None

        #~~ SHOULD IT BE AN ALARM?
        # TODO: add name of alarm if available?
        if secs >= 60 * 60 * 24:  # 24 hours in seconds
            if self.ask_yesno("timer.too.long.alarm.instead") == 'yes':
                alarm_time = now_local() + timedelta(seconds=secs)
                phrase = self.translate(
                    'set.alarm', {
                        'date': alarm_time.strftime('%B %d %Y'),
                        'time': alarm_time.strftime('%I:%M%p')
                    })
                self.bus.emit(
                    Message("recognizer_loop:utterance", {
                        "utterances": [phrase],
                        "lang": "en-us"
                    }))
            return

        #~~ CREATE TIMER
        self.timer_index += 1
        time_expires = datetime.now() + timedelta(seconds=secs)
        timer = {
            "name": timer_name,
            "index": self.timer_index,
            # keep track of ordinal until all timers of that name expire
            "ordinal": self._get_ordinal_of_new_timer(secs),
            "duration": secs,
            "expires": time_expires,
            "announced": False
        }
        self.active_timers.append(timer)
        self.log.debug("-------------TIMER-CREATED-------------")
        for key in timer:
            self.log.debug('creating timer: {}: {}'.format(key, timer[key]))
        self.log.debug("---------------------------------------")

        #~~ INFORM USER
        if timer['ordinal'] > 1:
            dialog = 'started.ordinal.timer'
        else:
            dialog = 'started.timer'
        if timer['name'] is not None:
            dialog += '.with.name'

        self.speak_dialog(dialog,
                          data={
                              "duration": nice_duration(timer["duration"]),
                              "name": timer["name"],
                              "ordinal": self._get_speakable_ordinal(timer)
                          })

        #~~ CLEANUP
        self.pickle()
        wait_while_speaking()
        self.enable_intent("handle_mute_timer")
        # Start showing the remaining time on the faceplate
        self.update_display(None)
        # reset the mute flag with a new timer
        self.mute = False
Exemplo n.º 10
0
def is_tomorrow(d):
    return d.date() == now_local().date() + timedelta(days=1)
Exemplo n.º 11
0
def is_today(d):
    return d.date() == now_local().date()
Exemplo n.º 12
0
import time
from os.path import dirname, join
from datetime import datetime, timedelta
from mycroft import MycroftSkill, intent_file_handler
from mycroft.util.parse import extract_datetime, normalize
from mycroft.util.time import now_local
from mycroft.util.format import nice_time, nice_date
from mycroft.util.log import LOG
from mycroft.util import play_wav
from mycroft.messagebus.client import MessageBusClient

REMINDER_PING = join(dirname(__file__), 'twoBeep.wav')

MINUTES = 60  # seconds

DEFAULT_TIME = now_local().replace(hour=8, minute=0, second=0)

def deserialize(dt):
    return datetime.strptime(dt, '%Y%d%m-%H%M%S-%z')


def serialize(dt):
    return dt.strftime('%Y%d%m-%H%M%S-%z')


def is_today(d):
    return d.date() == now_local().date()


def is_tomorrow(d):
    return d.date() == now_local().date() + timedelta(days=1)