def digest(self, timestr, default=None, ignoretz=False, tzinfos=None, **kwargs): if not default: default = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) seq = self._tokenize(timestr, **kwargs) if seq is None: raise ValueError, "unknown string format" repl = {} res = seq.dt_obj for attr in ["year", "month", "day", "hour", "minute", "second", "microsecond"]: value = getattr(res, attr) if value is not None: repl[attr] = value ret = default.replace(**repl) if res.weekday is not None and not res.day: ret = ret+relativedelta.relativedelta(weekday=res.weekday) if not ignoretz: if callable(tzinfos) or tzinfos and res.tzname in tzinfos: if callable(tzinfos): tzdata = tzinfos(res.tzname, res.tzoffset) else: tzdata = tzinfos.get(res.tzname) if isinstance(tzdata, datetime.tzinfo): tzinfo = tzdata elif isinstance(tzdata, basestring): tzinfo = tz.tzstr(tzdata) elif isinstance(tzdata, int): tzinfo = tz.tzoffset(res.tzname, tzdata) else: raise ValueError, "offset must be tzinfo subclass, " \ "tz string, or int offset" ret = ret.replace(tzinfo=tzinfo) elif res.tzname and res.tzname in time.tzname: ret = ret.replace(tzinfo=tz.tzlocal()) elif res.tzoffset == 0: ret = ret.replace(tzinfo=tz.tzutc()) elif res.tzoffset: ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) p = self._parseresult() p.pseq = seq p.res = res p.dt = ret return p
def parse(self, timestr, default=None, ignoretz=False, tzinfos=None, pastweekdays=False, **kwargs): if not default: default = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) res = self._parse(timestr, **kwargs) if res is None: raise ValueError, "unknown string format" repl = {} for attr in ["year", "month", "day", "hour", "minute", "second", "microsecond"]: value = getattr(res, attr) if value is not None: repl[attr] = value ret = default.replace(**repl) if res.weekday is not None and not res.day: wd = relativedelta.weekdays[res.weekday](pastweekdays and -1 or +1) ret = ret+relativedelta.relativedelta(weekday=wd) if not ignoretz: if callable(tzinfos) or tzinfos and res.tzname in tzinfos: if callable(tzinfos): tzdata = tzinfos(res.tzname, res.tzoffset) else: tzdata = tzinfos.get(res.tzname) if isinstance(tzdata, datetime.tzinfo): tzinfo = tzdata elif isinstance(tzdata, basestring): tzinfo = tz.tzstr(tzdata) elif isinstance(tzdata, int): tzinfo = tz.tzoffset(res.tzname, tzdata) else: raise ValueError, "offset must be tzinfo subclass, " \ "tz string, or int offset" ret = ret.replace(tzinfo=tzinfo) elif res.tzname and res.tzname in time.tzname: ret = ret.replace(tzinfo=tz.tzlocal()) elif res.tzoffset == 0: ret = ret.replace(tzinfo=tz.tzutc()) elif res.tzoffset: ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) return ret
def parse(self, timestr, default=None, ignoretz=False, tzinfos=None, **kwargs): if not default: default = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) res = self._parse(timestr, **kwargs) if res is None: raise ValueError("unknown string format") repl = {} for attr in ["year", "month", "day", "hour", "minute", "second", "microsecond"]: value = getattr(res, attr) if value is not None: repl[attr] = value ret = default.replace(**repl) if res.weekday is not None and not res.day: ret = ret+relativedelta.relativedelta(weekday=res.weekday) if not ignoretz: if isinstance(tzinfos, collections.Callable) or tzinfos and res.tzname in tzinfos: if isinstance(tzinfos, collections.Callable): tzdata = tzinfos(res.tzname, res.tzoffset) else: tzdata = tzinfos.get(res.tzname) if isinstance(tzdata, datetime.tzinfo): tzinfo = tzdata elif isinstance(tzdata, str): tzinfo = tz.tzstr(tzdata) elif isinstance(tzdata, int): tzinfo = tz.tzoffset(res.tzname, tzdata) else: raise ValueError("offset must be tzinfo subclass, " \ "tz string, or int offset") ret = ret.replace(tzinfo=tzinfo) elif res.tzname and res.tzname in time.tzname: ret = ret.replace(tzinfo=tz.tzlocal()) elif res.tzoffset == 0: ret = ret.replace(tzinfo=tz.tzutc()) elif res.tzoffset: ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) return ret
def gen(self, key, data=None, userid=None, site_id=None, timestamp=None): # pylint: disable=too-many-arguments # pylint: disable=too-many-locals # pylint: disable=too-many-statements # pylint: disable=too-many-branches """Generate an event. Arguments: key: The key to look up. data: A Dictionary with all of the event information. Recognized keys: - From http response: stdout stderr xid pid exit-status run-status timestamp - Sometimes added: error info - Available from AgentConnection: displayname agent_type uuid auth, which has: hostname ip-address version listen-port install-dir """ if data == None: data = {} if 'enabled' in data and not data['enabled']: logger.debug("Agent is disabled so no event will be " + \ "generated. key: %s, data: %s", key, data) return event_entry = self.get_event_control_entry(key) if event_entry: subject = event_entry.subject event_description = event_entry.event_description else: logger.error("No such event key: %s. data: %s\n", key, str(data)) return # add all system table entries to the data dictionary. data = dict(data.items() + \ self.system.todict(include_defaults=True).items()) logger.debug(key + " DATA: " + str(data)) if 'exit-status' in data: data['exit_status'] = data['exit-status'] del data['exit-status'] # FIXME: remove when browser-aware timezone support is available. if timestamp is None: timestamp = datetime.datetime.now(tz=tz.tzlocal()) logger.debug(key + " timestamp : " + timestamp.strftime(DATEFMT)) data['timestamp'] = timestamp.strftime(DATEFMT) # The userid for other events is the Palette "userid". profile = None if not 'username' in data and userid != None: profile = UserProfile.get(self.envid, userid) if not profile is None: data['username'] = profile.display_name() data['userid'] = profile.userid if profile.email: data['email'] = profile.email if userid: # userid passed to us has higher precedence than any # lookup we did, above. data['userid'] = userid if not 'username' in data: data['username'] = mako.runtime.UNDEFINED data['event_type'] = event_entry.event_type data['event_type_label'] = event_entry.event_type_label data['event_label'] = event_entry.event_label data['event_label_desc'] = event_entry.event_label_desc data['admin_visibility'] = event_entry.admin_visibility data['publisher_visiblity'] = event_entry.publisher_visibility # set server-url(s) data['server_url'] = self.system[SystemKeys.SERVER_URL] url = self.server.public_url() if url: data['tableau_server_url'] = url if not 'environment' in data: data['environment'] = self.server.environment.name if 'site_id' in data and 'site' not in data: site = Site.get_name_by_id(self.envid, data['site_id']) if not site is None: data['site'] = site if 'project_id' in data and 'project' not in data: project = Project.get_name_by_id(self.envid, data['project_id']) if not project is None: data['project'] = project # Create the row to get the eventid before doing subject/description # substitution. session = meta.DBSession() entry = EventEntry(complete=False, key='incomplete') # set the timestamp here in case it has tzinfo. entry.timestamp = timestamp session.add(entry) session.commit() data['eventid'] = entry.eventid # Use the data dict for template substitution. try: subject = subject % data except (ValueError, KeyError) as ex: subject = "Template subject conversion failure: " + str(ex) + \ "subject: " + subject + \ ", data: " + str(data) if event_description: try: mako_template = Template(event_description, default_filters=['h']) event_description = mako_template.render(**data) except MakoException: event_description = \ "Mako template message conversion failure: " + \ exceptions.text_error_template().render() + \ "\ntemplate: " + event_description + \ "\ndata: " + str(data) except TypeError as ex: event_description = \ "Mako template message conversion failure: " + \ str(ex) + \ "\ntemplate: " + event_description + \ "\ndata: " + str(data) else: event_description = self.make_default_description(data) event_description = re.sub("(\n|\r\n){3,}", "\n\n", event_description) if not event_description.endswith("\n"): event_description = event_description + "\n" if self.server.event_debug: event_description = event_description + "--------\n" + str(data) # FIXME: remove when browser-aware timezone support is available. if timestamp.tzinfo is None: # if not timezone is specified, assume UTC. summary = utc2local(timestamp).strftime(DATEFMT) else: summary = timestamp.strftime(DATEFMT) # Log the event to the database entry.complete = True entry.key = key entry.envid = self.envid entry.title = subject entry.description = event_description entry.level = event_entry.level entry.icon = event_entry.icon entry.color = event_entry.color entry.event_type = event_entry.event_type entry.summary = summary entry.userid = userid entry.site_id = site_id #entry.timestamp = timestamp session.merge(entry) session.commit() if not event_entry.send_email: return try: self.alert_email.send(event_entry, data, eventid=entry.eventid) except StandardError: exc_traceback = sys.exc_info()[2] tback = ''.join(traceback.format_tb(exc_traceback)) report = "Error: %s. Traceback: %s" % (sys.exc_info()[1], tback) logger.error( "alert_email: Failed for event '%s', '" "data '%s'. Will not send email. %s", event_entry.key, str(data), report)
def parse(self, timestr, default=None, ignoretz=False, tzinfos=None, fuzzyreturn=False, **kwargs): if not default: default = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) res = self._parse(timestr, **kwargs) if res is None: raise ValueError, "unknown string format" repl = {} for attr in ["year", "month", "day", "hour", "minute", "second", "microsecond"]: value = getattr(res, attr) if value is not None: repl[attr] = value ret = default.replace(**repl) if res.weekday is not None and not res.day: ret = ret + relativedelta.relativedelta(weekday=res.weekday) if not ignoretz: if callable(tzinfos) or tzinfos and res.tzname in tzinfos: if callable(tzinfos): tzdata = tzinfos(res.tzname, res.tzoffset) else: tzdata = tzinfos.get(res.tzname) if isinstance(tzdata, datetime.tzinfo): tzinfo = tzdata elif isinstance(tzdata, basestring): tzinfo = tz.tzstr(tzdata) elif isinstance(tzdata, int): tzinfo = tz.tzoffset(res.tzname, tzdata) else: raise ValueError, "offset must be tzinfo subclass, " "tz string, or int offset" ret = ret.replace(tzinfo=tzinfo) elif res.tzname and res.tzname in time.tzname: ret = ret.replace(tzinfo=tz.tzlocal()) elif res.tzoffset == 0: ret = ret.replace(tzinfo=tz.tzutc()) elif res.tzoffset: ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) if fuzzyreturn: if not repl.has_key("month"): # return a fuzzy answer: an object representing a whole year return relativedelta.relativedelta(year=ret.year, years=+1) elif not repl.has_key("day"): # return a fuzzy answer: an object representing a whole month return relativedelta.relativedelta(year=ret.year, month=ret.month, months=+1) elif not repl.has_key("hour"): # return a fuzzy answer: an object representing a whole day return relativedelta.relativedelta(year=ret.year, month=ret.month, day=ret.day, days=+1) elif not repl.has_key("minute"): # return a fuzzy answer: an object representing a whole hour return relativedelta.relativedelta(year=ret.year, month=ret.month, day=ret.day, hour=ret.hour, hours=+1) elif not repl.has_key("second"): # return a fuzzy answer: an object representing a whole minute return relativedelta.relativedelta( year=ret.year, month=ret.month, day=ret.day, hour=ret.hour, minute=ret.minute, minutes=+1 ) elif not repl.has_key("microsecond"): # return a fuzzy answer: an object representing a whole second return relativedelta.relativedelta( year=ret.year, month=ret.month, day=ret.day, hour=ret.hour, minute=ret.minute, second=ret.second, seconds=+1, ) return ret