# Path: protector/influxdb/daterange.py
# class DateRange(object):
#     """
#     A thin abstraction layer for date ranges
#     """
# 
#     def __init__(self, start, end):
#         self.start = start
#         self.end = end
# 
#     def timespan(self):
#         return self.end - self.start
# 
#     def timespan_seconds(self):
#         t = self.timespan()
#         # A duration can never be negative
#         return max(0, t.total_seconds())
# 
#     def __str__(self):
#         return "Start: {}, End: {}, (Time span: {})".format(self.start, self.end, self.timespan())
# 
#     def __repr__(self):
#         return self.__str__()
# 
#     def __eq__(self, other):
#         if isinstance(other, self.__class__):
#             return (self.start == other.start) and (self.end == other.end)
#         else:
#             return False
# 
#     def __ne__(self, other):
#         return not self.__eq__(other)
# 
# Path: protector/influxdb/time_expression.py
# class TimeExpression(object):
#     # Smallest possible system date.
#     # This is required for the calculation of the max duration between datetime objects.
#     # We use the release day of InfluxDB 0.8 as the epoch
#     # because it is the first official version supported by this tool.
#     INFLUXDB_EPOCH = datetime.strptime('2014-08-22', "%Y-%m-%d")
# 
#     # Full names of all supported relative time units.
#     # Useful for conversions of the internal InfluxDB format to the Python timedelta format.
#     UNIT_NAMES = {
#         'u': 'microseconds',
#         's': 'seconds',
#         'm': 'minutes',
#         'h': 'hours',
#         'd': 'days',
#         'w': 'weeks'
#     }
# 
#     # Conversions of all InfluxDB relative time units to seconds.
#     # Useful for datapoint calculations.
#     UNIT_CONVERSION = {'u': 0.001, 's': 1, 'm': 60, 'h': 3600, 'd': 86400, 'w': 604800}


import re
from datetime import datetime, timedelta
from protector.influxdb.daterange import DateRange
from protector.influxdb.time_expression import TimeExpression
    def _create_timedelta(value, unit):
        if unit not in TimeExpression.UNIT_NAMES.keys():
            # Invalid query
            return None
        params = {TimeExpression.UNIT_NAMES[unit]: value}
        return timedelta(**params)

    @staticmethod
    def parse_date_time(match):
        text = match.group(1)
        for fmt in ('%Y-%m-%d', '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f'):
            try:
                return datetime.strptime(text, fmt)
            except ValueError:
                pass
        raise ValueError('No valid date format found')

    @staticmethod
    def parse_unix_time(match):
        ts_string = match.group(1)
        # Truncate milliseconds
        ts = int(ts_string[:10])
        return datetime.fromtimestamp(ts)

    def _create_time(self, comparison_operator, datetime_obj):
        if comparison_operator == '=':
            return DateRange(datetime_obj, datetime_obj)
        elif comparison_operator == '>':
            return DateRange(datetime_obj, datetime.now())
        elif comparison_operator == '<':

# Path: protector/influxdb/daterange.py
# class DateRange(object):
#     """
#     A thin abstraction layer for date ranges
#     """
# 
#     def __init__(self, start, end):
#         self.start = start
#         self.end = end
# 
#     def timespan(self):
#         return self.end - self.start
# 
#     def timespan_seconds(self):
#         t = self.timespan()
#         # A duration can never be negative
#         return max(0, t.total_seconds())
# 
#     def __str__(self):
#         return "Start: {}, End: {}, (Time span: {})".format(self.start, self.end, self.timespan())
# 
#     def __repr__(self):
#         return self.__str__()
# 
#     def __eq__(self, other):
#         if isinstance(other, self.__class__):
#             return (self.start == other.start) and (self.end == other.end)
#         else:
#             return False
# 
#     def __ne__(self, other):
#         return not self.__eq__(other)
# 
# Path: protector/influxdb/time_expression.py
# class TimeExpression(object):
#     # Smallest possible system date.
#     # This is required for the calculation of the max duration between datetime objects.
#     # We use the release day of InfluxDB 0.8 as the epoch
#     # because it is the first official version supported by this tool.
#     INFLUXDB_EPOCH = datetime.strptime('2014-08-22', "%Y-%m-%d")
# 
#     # Full names of all supported relative time units.
#     # Useful for conversions of the internal InfluxDB format to the Python timedelta format.
#     UNIT_NAMES = {
#         'u': 'microseconds',
#         's': 'seconds',
#         'm': 'minutes',
#         'h': 'hours',
#         'd': 'days',
#         'w': 'weeks'
#     }
# 
#     # Conversions of all InfluxDB relative time units to seconds.
#     # Useful for datapoint calculations.
#     UNIT_CONVERSION = {'u': 0.001, 's': 1, 'm': 60, 'h': 3600, 'd': 86400, 'w': 604800}


# Path: protector/parser/subparsers/time_range.py
import re
from datetime import datetime, timedelta
from protector.influxdb.daterange import DateRange
from protector.influxdb.time_expression import TimeExpression

    def _create_timedelta(value, unit):
        if unit not in TimeExpression.UNIT_NAMES.keys():
            # Invalid query
            return None
        params = {TimeExpression.UNIT_NAMES[unit]: value}
        return timedelta(**params)

    @staticmethod
    def parse_date_time(match):
        text = match.group(1)
        for fmt in ('%Y-%m-%d', '%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f'):
            try:
                return datetime.strptime(text, fmt)
            except ValueError:
                pass
        raise ValueError('No valid date format found')

    @staticmethod
    def parse_unix_time(match):
        ts_string = match.group(1)
        # Truncate milliseconds
        ts = int(ts_string[:10])
        return datetime.fromtimestamp(ts)

    def _create_time(self, comparison_operator, datetime_obj):
        if comparison_operator == '=':
            return DateRange(datetime_obj, datetime_obj)
        elif comparison_operator == '>':
            return DateRange(datetime_obj, datetime.now())
        elif comparison_operator == '<':

            return DateRange(self.epoch, datetime_obj)