""" Utility functions for fingerprint sweeper """ from datetime import date, datetime, timedelta import sys import time import uuid from fpsweeper.connector import sentry from fpsweeper.context import context def yield_sublists(arg_list, sublist_size): """Yield successive sublist_size length chunks from arg_list Example usage: my_list = [x for x in range(0, 100)] for sublist in yield_sublists(my_list, 10): print(sublist) Args: arg_list (list): list to divide sublist_size (int): size of each sublist returned Returns: sublist (generator list) """ for i in range(0, len(arg_list), sublist_size): yield arg_list[i:i + sublist_size] def get_timestamp_utc_iso8601(include_zone_designator=True): """Get a UTC ISO8601 timestamp with microsecond precision Example output: 2016-01-15T18:39:42.574031Z Args: include_zone_designator (bool): if True, include the UTC zone designator (Z) at end including this option, because mysql issues a truncation warning for zone designator Returns: timestamp (str): current timestamp """ zone_designator = 'Z' if include_zone_designator else '' return datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f{}".format(zone_designator)) def get_datetime_utc_iso8601_seconds_ago(seconds_ago, include_zone_designator=True): """Get the datetime for given seconds_ago with microsecond precision. For example, if now is '2016-02-03T18:01:11.054818Z', and seconds_ago is 3600, return '2016-02-03T17:01:11.054818Z'. Args: seconds_ago (int): number of seconds to subtract from current time include_zone_designator (bool): if True, include the UTC zone designator (Z) at end including this option, because mysql issues a truncation warning for zone designator Returns: UTC ISO8601-formatted datetime string """ zone_designator = 'Z' if include_zone_designator else '' return (datetime.utcnow() - timedelta(seconds=seconds_ago))\ .strftime("%Y-%m-%dT%H:%M:%S.%f{}".format(zone_designator)) def get_date_utc_iso8601_days_ago(days_ago, include_zone_designator=True): """Get the date for given days_ago with microseconds precison. Time will be 00:00:00.000000 For example, if now is '2016-02-03T18:01:11.054818Z' and days_ago is 5, return '2016-01-29T00:00:00.000000Z' Args: days_ago (int): number of days to subtract from current time include_zone_designator (bool): if True, include the UTC zone designator (Z) at end including this option, because mysql issues a truncation warning for zone designator Returns: UTC ISO8601-formatted datetime string """ zone_designator = 'Z' if include_zone_designator else '' return (date.today() - timedelta(days=days_ago))\ .strftime("%Y-%m-%dT%H:%M:%S.%f{}".format(zone_designator)) def get_unix_timestamp(): """return a unix timestamp in integer form """ return int(time.time()) def create_correlation_id(): """Create an id that is used to correlate logs Returns: correlation_id (str) """ return str(uuid.uuid1()) def try_execute_query(db_session, clause, params=None): """Try to execute a query and return the results. If exception occurs, report it to Sentry, log it, and re-raise exception Args: db_session (sqlalchemy.orm.session.Session) clause (sqlalchemy.sql.text or string): sql to execute params (dictionary): query params Returns: query results (sqlalchemy.engine.result.ResultProxy) """ try: return db_session.execute(clause, params) except: # catch all exceptions sentry.sentry_client.captureException() context.logger.error("Error executing db query: {}".format(sys.exc_info()[1])) raise