def test_nice_date(self): lang = "cs-cz" i = 1 while (self.test_config[lang].get('test_nice_date') and self.test_config[lang]['test_nice_date'].get(str(i).encode('utf8'))): p = self.test_config[lang]['test_nice_date'][str(i)] dp = ast.literal_eval(p['datetime_param']) np = ast.literal_eval(p['now']) dt = datetime.datetime( dp[0], dp[1], dp[2], dp[3], dp[4], dp[5]) now = None if not np else datetime.datetime( np[0], np[1], np[2], np[3], np[4], np[5]) print('Testing for ' + lang + ' that ' + str(dt) + ' is date ' + p['assertEqual']) self.assertEqual(p['assertEqual'], nice_date(dt, lang=lang, now=now)) i = i + 1 # test fall back to english !!!Skiped #dt = datetime.datetime(2018, 2, 4, 0, 2, 3) # self.assertEqual(nice_date( # dt, lang='invalid', now=datetime.datetime(2018, 2, 4, 0, 2, 3)), # 'today') # test all days in a year for all languages, # that some output is produced # for lang in self.test_config: for dt in (datetime.datetime(2017, 12, 30, 0, 2, 3) + datetime.timedelta(n) for n in range(368)): self.assertTrue(len(nice_date(dt, lang=lang)) > 0)
def update_picture(self): try: url = "https://epic.gsfc.nasa.gov/api/natural" self.settings["raw_data"] = self.session.get(url).json() except Exception as e: self.log.exception(e) response = self.settings["raw_data"][-1] url = "https://epic.gsfc.nasa.gov/epic-archive/jpg/" + response[ "image"] + ".jpg" self.gui['imgLink'] = self.settings['imgLink'] = url for k in response: if k in ['identifier', 'version', 'image']: continue self.settings[k] = response[k] self.gui[k] = response[k] self.settings["spoken_date"] = self.gui["spoken_date"] = \ nice_date(datetime.today(), lang=self.lang) self.gui['title'] = response['date'] self.settings["animation"] = self.gui["animation"] = self._create_gif() self.set_context("BlueMarble") return self.gui['imgLink']
def _display(self, date, location, silent=False): lat, lon = None, None self.gui["location"] = self.location_pretty if location: try: lat, lon = self.geolocate(location) except: self.speak_dialog("location.error", {"location": location}) return self.gui["location"] = location self.update_picture(date=date, lat=lat, lon=lon) if date: # TODO validate date and speak error message if in future # will still display most recent, but want to signal user if isinstance(date, str): date = datetime.strptime(date, "%Y-%m-%d") delta = date - self.current_date if delta: self.speak_dialog("bad.date") self.gui.show_image(self.gui['imgLink'], title=self.gui['title'], caption=self.gui["caption"], fill='PreserveAspectFit') date = nice_date(self.current_date, lang=self.lang) if silent: return if location: self.speak_dialog("location", { "date": date, "location": location }, wait=True) else: self.speak_dialog("house", {"date": date}, wait=True)
def update_latest(self): try: today = datetime.today() if not self.settings.get("ts"): self.settings["ts"] = (today - timedelta(days=1)).timestamp() if today.timestamp() != self.settings["ts"] or \ not self.settings.get('imgLink'): self.settings["raw_data"] = self.get_latest() comic_date = date(day=int(self.settings["raw_data"]["day"]), month=int( self.settings["raw_data"]["month"]), year=int(self.settings["raw_data"]["year"])) self.settings["imgLink"] = self.settings["raw_data"]["img"] self.settings["title"] = self.settings["raw_data"][ "safe_title"] self.settings["caption"] = self.settings["raw_data"]["alt"] self.settings["date"] = str(comic_date) self.settings["spoken_date"] = nice_date(comic_date, lang=self.lang) self.settings["ts"] = comic_date.timestamp() except Exception as e: self.log.exception(e) self.gui['imgLink'] = self.settings['imgLink'] self.gui['title'] = self.settings['title'] self.gui['date'] = self.settings['date'] self.gui['spoken_date'] = self.settings['spoken_date'] self.gui['caption'] = self.settings['caption']
def annotate_datetime(self, text): date, value, rem = _annotate_datetime_en(text, self.anchor_date) while value: try: data = { "timestamp": date.timestamp(), "isoformat": date.isoformat(), "weekday": date.isoweekday(), "month": date.month, "day": date.day, "hour": date.hour, "minute": date.minute, "year": date.year, "spoken": nice_date(date, now=self.anchor_date) } yield Entity(value, "relative_date", source_text=text, data=data) except OverflowError: # deep past / future yield Entity(value, "date", source_text=text, data={"spoken": value}) if not rem: return date, value, rem = _annotate_datetime_en(rem, self.anchor_date)
def handle_ask_specific(self, message): """Intent handler to tell the user his appointments on specific days. Gets executed with the right user input. The user can ask e.g for a specific day, or if he has any appointments in two weeks. Args: message: A message object, which contains the user inputs. In this case the message contains the specific date. """ date = message.data['date'] try: start_date = extract_datetime(date)[0] end_date = datetime.combine(start_date, start_date.max.time()) calendar = self.current_calendar if calendar is None: self.speak('No calendar accessible') return events = self.get_all_events( calendar=calendar, start=start_date.astimezone(self.local_tz), end=end_date.astimezone(self.local_tz)) spoken_date = nice_date(start_date) if len(events) == 0: self.speak_dialog('no.appointments.specific', {'date': spoken_date}) next_event = self.get_all_events(calendar=calendar, start=start_date.astimezone(self.local_tz)) # Mycroft needs full lenght. pylint: disable=line-too-long if len(next_event) > 0: start_date_string = f"{self.get_ordinal_number(next_event[0].instance.vevent.dtstart.value.day)} of {next_event[0].instance.vevent.dtstart.value.strftime('%B')}" # Mycroft needs full lenght. pylint: disable=line-too-long summary = self.get_event_title( next_event[0].instance.vevent) self.speak_dialog('yes.next.appointment.specific', { 'title': summary, 'date': start_date_string }) elif len(events) >= 1: self.speak_dialog('yes.appointments.specific', {'number': len(events), 'date': spoken_date}) # Mycroft needs full lenght. pylint: disable=line-too-long for event in events: next_event = event.instance.vevent self.helper_speak_event(next_event) except TypeError as type_error: self.log.error(type_error) self.speak( f"{date} is not a valid input. Please rephrase your question.") except Exception as exception: # We want to catch all types of exceptions pylint: disable=broad-except self.log.error(exception) self.speak("Unexpected error! Check Logs!")
def test_nice_date(self): for lang in self.test_config: i = 1 while (self.test_config[lang].get('test_nice_date') and self.test_config[lang]['test_nice_date'].get(str(i))): p = self.test_config[lang]['test_nice_date'][str(i)] dp = ast.literal_eval(p['datetime_param']) np = ast.literal_eval(p['now']) dt = datetime.datetime( dp[0], dp[1], dp[2], dp[3], dp[4], dp[5]) now = None if not np else datetime.datetime( np[0], np[1], np[2], np[3], np[4], np[5]) print('Testing for ' + lang + ' that ' + str(dt) + ' is date ' + p['assertEqual']) self.assertEqual(p['assertEqual'], nice_date(dt, lang=lang, now=now)) i = i + 1 # test all days in a year for all languages, # that some output is produced for lang in self.test_config: for dt in (datetime.datetime(2017, 12, 30, 0, 2, 3) + datetime.timedelta(n) for n in range(368)): self.assertTrue(len(nice_date(dt, lang=lang)) > 0)
def test_nice_date(self): for lang in self.test_config: i = 1 while (self.test_config[lang].get('test_nice_date') and self.test_config[lang]['test_nice_date'].get(str(i))): p = self.test_config[lang]['test_nice_date'][str(i)] dp = ast.literal_eval(p['datetime_param']) np = ast.literal_eval(p['now']) dt = datetime.datetime(dp[0], dp[1], dp[2], dp[3], dp[4], dp[5]) now = None if not np else datetime.datetime( np[0], np[1], np[2], np[3], np[4], np[5]) print('Testing for ' + lang + ' that ' + str(dt) + ' is date ' + p['assertEqual']) self.assertEqual(p['assertEqual'], nice_date(dt, lang=lang, now=now)) i = i + 1
def handle_space_launch_intent(self, message): try: r = requests.get("https://launchlibrary.net/1.2/launch/next/1" "").json() dt = datetime.strptime(r['launches'][0]["windowstart"], "%B %d, %Y %H:%M:%S UTC") image = r['launches'][0]["rocket"]["imageURL"] description = str(r['launches'][0]["missions"][0]["description"]) rocket = str(r['launches'][0]['rocket']['name']) location = str(r['launches'][0]['location']['pads'][0]['name']) now = datetime.now() delta = dt - now if delta <= timedelta(days=2): date_time = nice_duration(delta, lang=self.lang, speech=True) self.speak_dialog("space.launch.delta", data={ 'rocket': rocket, 'delta': date_time, 'location': location }) else: date_time = nice_date(dt, lang=self.lang, now=now) self.speak_dialog("space.launch", data={ 'rocket': rocket, 'time': date_time, 'location': location }) self.gui.show_image( image, caption=location, title=rocket, override_idle=True, fill='PreserveAspectFit', ) self.set_context("launch_description", description) self.set_context("rocketPic", image) self.set_context("rocket", rocket) except Exception as e: self.log.error(e) self.speak_dialog("not.found")
def handle_semester_start(self, message): # first figure out if they want to know about the fall or spring semester month = date.today().month term = "spring" if month > 5 and month < 10: term = "fall" if "term" in message.data: term = message.data["term"] self.log.info(f"asking about the start of the {term} semester") # get the data from out dicts key = "first-day-" + term event = events[key] event["start"] = nice_date(date.fromisoformat(event["start"])) # send the data to the dialog self.speak_dialog("event", event)
def update_picture(self, idx=None, date=None): data = self.get_news() if idx is not None: data = data[idx] self.current_news = idx elif date is not None: if isinstance(date, datetime): date = date.date() def nearest(items, pivot): return min(items, key=lambda x: abs(x - pivot)) dates = [d["datetime"].date() for d in data] date = nearest(dates, date) for d in data: if d["date_str"] == str(date): data = d break else: data = data[0] self.current_news = 0 # TODO error dialog else: data = data[0] self.current_news = 0 data = dict(self._tx_keys(data)) date = data.pop("datetime") for k in data: self.gui[k] = data[k] self.set_context("space") self.set_context("url", data["url"]) self.settings["raw"] = data data["human_date"] = nice_date(date, lang=self.lang) self.set_context("SpaceNews") return data
def update_latest(self): try: self.settings["raw_data"] = self.get_latest() comic_date = date(day=int(self.settings["raw_data"]["day"]), month=int( self.settings["raw_data"]["month"]), year=int(self.settings["raw_data"]["year"])) self.settings["imgLink"] = self.settings["raw_data"]["img"] self.settings["title"] = self.settings["raw_data"]["safe_title"] self.settings["caption"] = self.settings["raw_data"]["alt"] self.settings["date"] = str(comic_date) self.settings["spoken_date"] = nice_date(comic_date, lang=self.lang) except Exception as e: self.log.exception(e) self.current_comic = self.total_comics() self.gui['imgLink'] = self.settings['imgLink'] self.gui['title'] = self.settings['title'] self.gui['date'] = self.settings['date'] self.gui['spoken_date'] = self.settings['spoken_date'] self.gui['caption'] = self.settings['caption']
assert pronounce_number(100034000000299792458, short_scale=True) == \ "one hundred quintillion, thirty four quadrillion, " \ "two hundred and ninety nine million, seven hundred and ninety " \ "two thousand, four hundred and fifty eight" assert pronounce_number(100034000000299792458, short_scale=False) == \ "one hundred trillion, thirty four thousand billion, " \ "two hundred and ninety nine million, seven hundred and ninety " \ "two thousand, four hundred and fifty eight" # pronounce datetime objects import datetime dt = datetime.datetime(2017, 1, 31, 13, 22, 3) assert nice_date(dt) == "tuesday, january thirty-first, twenty seventeen" assert nice_time(dt) == "one twenty two" assert nice_time(dt, use_ampm=True) == "one twenty two p.m." assert nice_time(dt, speech=False) == "1:22" assert nice_time(dt, speech=False, use_ampm=True) == "1:22 PM" assert nice_time(dt, speech=False, use_24hour=True) == "13:22" assert nice_time(dt, speech=False, use_24hour=True, use_ampm=True) == "13:22" assert nice_time(dt, use_24hour=True, use_ampm=True) == "thirteen twenty two" assert nice_time(dt, use_24hour=True, use_ampm=False) == "thirteen twenty two" assert nice_date_time(dt) == "tuesday, january thirty-first, twenty seventeen at one twenty two" # pronounce durations assert nice_duration(1) == "one second" assert nice_duration(3) == "three seconds"
def get_silso(self): url = "http://www.sidc.be/silso/DATA/EISN/EISN_current.txt" # Line format [character position]: # - [1-4] Year # - [6-8] Month # - [9-10] Day # - [12-19] Decimal date # - [21-23] Estimated Sunspot Number # - [25-29] Estimated Standard Deviation # - [31-33] Number of Stations calculated # - [35-37] Number of Stations available txt = self.session.get(url).text data_points = [] lines = txt.split("\n") for idx, line in enumerate(lines): if not line.strip(): continue date = datetime(year=int(line[:4].strip()), month=int(line[5:8].strip()), day=int(line[8:10].strip())) date = date.date() picture_url = "https://sohowww.nascom.nasa.gov/data/synoptic/sunspots/sunspots_1024_{y}{m}{d}.jpg" \ .format(y=date.year, m="{:02d}".format(date.month), d="{:02d}".format(date.day)) n = int(line[20:23].strip()) decrease = False increase = False change = 0 if idx > 0: prev = int(lines[idx - 1][20:23].strip()) if prev != n: pcchange = float(n / (prev + 0.000000001)) if pcchange < 0.5: decrease = True if pcchange >= 2: increase = True change = n - prev # title + caption title = "Sunspots - " + str(date) caption = str(n) + " sunspots" if increase: caption += "\nA significant increase with " + \ str(change) + " new spots" elif decrease: caption += "\nA significant decrease with " + \ str(abs(change)) + " less spots" data = { "date_str": str(date), "human_date": nice_date(date, lang=self.lang), "title": title, "caption": caption, "imgLink": picture_url, "count": n, "standard_deviation": float(line[24:29].strip()), "n_stations": int(line[30:33].strip()), "total_stations": int(line[34:37].strip()), "increase": increase, "decrease": decrease, "change": change } data_points.append(data) return data_points