def _show_alert_information(self, weather): items = [] if 'alerts' in weather: for alert in weather['alerts']: item = Item(alert['description'], icon='error.png') if alert['expires']: item.subtitle = 'Expires at {}'.format(alert['expires'].strftime( self.config['time_format'])) if 'uri' in alert: item.arg = clean_str(alert['uri']) item.valid = True items.append(item) return items
def _show_alert_information(self, weather): items = [] if 'alerts' in weather: for alert in weather['alerts']: item = Item(alert['description'], icon='error.png') if alert['expires']: item.subtitle = 'Expires at {}'.format( alert['expires'].strftime(self.config['time_format'])) if 'uri' in alert: item.arg = clean_str(alert['uri']) item.valid = True items.append(item) return items
def tell_query(self, query, start=None, end=None): '''List entries that match a query. Note that an end time without a start time will be ignored.''' LOG.info('tell_query("{0}", start={1}, end={2})'.format( query, start, end)) if not start: end = None needs_refresh = False query = query.strip() if self.cache.get('disable_cache', False): LOG.debug('cache is disabled') needs_refresh = True elif self.cache.get('time') and self.cache.get('time_entries'): last_load_time = self.cache.get('time') LOG.debug('last load was %s', last_load_time) import time now = int(time.time()) if now - last_load_time > CACHE_LIFETIME: LOG.debug('automatic refresh') needs_refresh = True else: LOG.debug('cache is missing timestamp or data') needs_refresh = True if needs_refresh: LOG.debug('refreshing cache') try: all_entries = toggl.TimeEntry.all() except Exception: LOG.exception('Error getting time entries') raise Exception('Problem talking to toggl.com') import time self.cache['time'] = int(time.time()) self.cache['time_entries'] = serialize_entries(all_entries) else: LOG.debug('using cached data') all_entries = deserialize_entries(self.cache['time_entries']) LOG.debug('%d entries', len(all_entries)) if start: LOG.debug('filtering on start time %s', start) if end: LOG.debug('filtering on end time %s', end) all_entries = [ e for e in all_entries if e.start_time < end and e.stop_time > start ] else: all_entries = [e for e in all_entries if e.stop_time > start] LOG.debug('filtered to %d entries', len(all_entries)) efforts = {} # group entries with the same description into efforts (so as not to be # confused with Toggl tasks for entry in all_entries: if entry.description not in efforts: efforts[entry.description] = Effort(entry.description, start, end) efforts[entry.description].add(entry) efforts = efforts.values() efforts = sorted(efforts, reverse=True, key=lambda e: e.newest_entry.start_time) items = [] if start: if len(efforts) > 0: seconds = sum(e.seconds for e in efforts) LOG.debug('total seconds: %s', seconds) total_time = to_hours_str(seconds) if end: item = Item('{0} hours on {1}'.format( total_time, start.date().strftime(DATE_FORMAT)), subtitle=Item.LINE) else: item = Item('{0} hours from {1}'.format( total_time, start.date().strftime(DATE_FORMAT)), subtitle=Item.LINE) else: item = Item('Nothing to report') items.append(item) show_suffix = start or end for effort in efforts: item = Item(effort.description, valid=True) now = LOCALTZ.localize(datetime.datetime.now()) newest_entry = effort.newest_entry if newest_entry.is_running: item.icon = 'running.png' started = newest_entry.start_time delta = to_approximate_time(now - started) seconds = effort.seconds total = '' if seconds > 0: hours = to_hours_str(seconds, show_suffix=show_suffix) total = ' ({0} hours total)'.format(hours) item.subtitle = 'Running for {0}{1}'.format(delta, total) item.arg = 'stop|{0}|{1}'.format(newest_entry.id, effort.description) else: seconds = effort.seconds hours = to_hours_str(datetime.timedelta(seconds=seconds), show_suffix=show_suffix) if start: item.subtitle = ('{0} hours'.format(hours)) else: stop = newest_entry.stop_time if stop: delta = to_approximate_time(now - stop, ago=True) else: delta = 'recently' oldest = effort.oldest_entry since = oldest.start_time since = since.strftime('%m/%d') item.subtitle = ('{0} hours since {1}, ' 'stopped {2}'.format(hours, since, delta)) item.arg = 'continue|{0}|{1}'.format(newest_entry.id, effort.description) items.append(item) if len(query.strip()) > 1: # there's a filter test = query[1:].strip() items = self.fuzzy_match_list(test, items, key=lambda t: t.title) if len(items) == 0: items.append(Item("Nothing found")) return items
def tell_query(self, query, start=None, end=None): '''List entries that match a query. Note that an end time without a start time will be ignored.''' LOG.info('tell_query("{0}", start={1}, end={2})'.format( query, start, end)) if not start: end = None needs_refresh = False query = query.strip() if self.cache.get('disable_cache', False): LOG.debug('cache is disabled') needs_refresh = True elif self.cache.get('time') and self.cache.get('time_entries'): last_load_time = self.cache.get('time') LOG.debug('last load was %s', last_load_time) import time now = int(time.time()) if now - last_load_time > CACHE_LIFETIME: LOG.debug('automatic refresh') needs_refresh = True else: LOG.debug('cache is missing timestamp or data') needs_refresh = True if needs_refresh: LOG.debug('refreshing cache') try: all_entries = toggl.TimeEntry.all() except Exception: LOG.exception('Error getting time entries') raise Exception('Problem talking to toggl.com') import time self.cache['time'] = int(time.time()) self.cache['time_entries'] = serialize_entries(all_entries) else: LOG.debug('using cached data') all_entries = deserialize_entries(self.cache['time_entries']) LOG.debug('%d entries', len(all_entries)) if start: LOG.debug('filtering on start time %s', start) if end: LOG.debug('filtering on end time %s', end) all_entries = [e for e in all_entries if e.start_time < end and e.stop_time > start] else: all_entries = [e for e in all_entries if e.stop_time > start] LOG.debug('filtered to %d entries', len(all_entries)) efforts = {} # group entries with the same description into efforts (so as not to be # confused with Toggl tasks for entry in all_entries: if entry.description not in efforts: efforts[entry.description] = Effort(entry.description, start, end) efforts[entry.description].add(entry) efforts = efforts.values() efforts = sorted(efforts, reverse=True, key=lambda e: e.newest_entry.start_time) items = [] if start: if len(efforts) > 0: seconds = sum(e.seconds for e in efforts) LOG.debug('total seconds: %s', seconds) total_time = to_hours_str(seconds) if end: item = Item('{0} hours on {1}'.format( total_time, start.date().strftime(DATE_FORMAT)), subtitle=Item.LINE) else: item = Item('{0} hours from {1}'.format( total_time, start.date().strftime(DATE_FORMAT)), subtitle=Item.LINE) else: item = Item('Nothing to report') items.append(item) show_suffix = start or end for effort in efforts: item = Item(effort.description, valid=True) now = LOCALTZ.localize(datetime.datetime.now()) newest_entry = effort.newest_entry if newest_entry.is_running: item.icon = 'running.png' started = newest_entry.start_time delta = to_approximate_time(now - started) seconds = effort.seconds total = '' if seconds > 0: hours = to_hours_str(seconds, show_suffix=show_suffix) total = ' ({0} hours total)'.format(hours) item.subtitle = 'Running for {0}{1}'.format(delta, total) item.arg = 'stop|{0}|{1}'.format(newest_entry.id, effort.description) else: seconds = effort.seconds hours = to_hours_str(datetime.timedelta(seconds=seconds), show_suffix=show_suffix) if start: item.subtitle = ('{0} hours'.format(hours)) else: stop = newest_entry.stop_time if stop: delta = to_approximate_time(now - stop, ago=True) else: delta = 'recently' oldest = effort.oldest_entry since = oldest.start_time since = since.strftime('%m/%d') item.subtitle = ('{0} hours since {1}, ' 'stopped {2}'.format(hours, since, delta)) item.arg = 'continue|{0}|{1}'.format(newest_entry.id, effort.description) items.append(item) if len(query.strip()) > 1: # there's a filter test = query[1:].strip() items = self.fuzzy_match_list(test, items, key=lambda t: t.title) if len(items) == 0: items.append(Item("Nothing found")) return items