mirror of https://github.com/MISP/PyMISP
chg: Normalize to_datetime conversion
parent
32445973bd
commit
f43266fcf2
|
@ -4,6 +4,7 @@ from datetime import timezone, datetime, date
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
|
import sys
|
||||||
from io import BytesIO, IOBase
|
from io import BytesIO, IOBase
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
import uuid
|
import uuid
|
||||||
|
@ -51,6 +52,42 @@ def _int_to_str(d: dict):
|
||||||
d[k] = str(v)
|
d[k] = str(v)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def _make_datetime(value) -> datetime:
|
||||||
|
if isinstance(value, (int, float)):
|
||||||
|
# Timestamp
|
||||||
|
value = datetime.fromtimestamp(value)
|
||||||
|
elif isinstance(value, str):
|
||||||
|
if sys.version_info >= (3, 7):
|
||||||
|
try:
|
||||||
|
# faster
|
||||||
|
value = datetime.fromisoformat(value)
|
||||||
|
except Exception:
|
||||||
|
value = parse(value)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
# faster
|
||||||
|
if '+' in value or '-' in value:
|
||||||
|
value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
|
elif '.' in value:
|
||||||
|
value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")
|
||||||
|
elif 'T' in value:
|
||||||
|
value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S")
|
||||||
|
else:
|
||||||
|
value = datetime.strptime(value, "%Y-%m-%d")
|
||||||
|
except Exception:
|
||||||
|
value = parse(value)
|
||||||
|
elif isinstance(value, date):
|
||||||
|
value = datetime.combine(value, datetime.min.time())
|
||||||
|
elif isinstance(value, datetime):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise PyMISPError(f'Invalid format for {value}: {type(value)}.')
|
||||||
|
|
||||||
|
if not value.tzinfo:
|
||||||
|
# set localtimezone if not present
|
||||||
|
value = value.astimezone()
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def make_bool(value: Union[bool, int, str, dict, list, None]) -> bool:
|
def make_bool(value: Union[bool, int, str, dict, list, None]) -> bool:
|
||||||
if isinstance(value, bool):
|
if isinstance(value, bool):
|
||||||
|
@ -179,21 +216,7 @@ class MISPAttribute(AbstractMISP):
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
if name in ['first_seen', 'last_seen']:
|
if name in ['first_seen', 'last_seen']:
|
||||||
if isinstance(value, (int, float)):
|
value = _make_datetime(value)
|
||||||
# Timestamp
|
|
||||||
value = datetime.fromtimestamp(value)
|
|
||||||
elif isinstance(value, str):
|
|
||||||
value = parse(value)
|
|
||||||
elif isinstance(value, date):
|
|
||||||
value = datetime.combine(falue, datetime.min.time())
|
|
||||||
elif isinstance(value, datetime):
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise PyMISPError(f'Invalid format for {name}: {type(value)}.')
|
|
||||||
|
|
||||||
if not value.tzinfo:
|
|
||||||
# set localtimezone if not present
|
|
||||||
value = value.astimezone()
|
|
||||||
|
|
||||||
if name == 'last_seen' and hasattr(self, 'first_seen') and self.first_seen > value:
|
if name == 'last_seen' and hasattr(self, 'first_seen') and self.first_seen > value:
|
||||||
raise PyMISPError('last_seen ({value}) has to be after first_seen ({self.first_seen})')
|
raise PyMISPError('last_seen ({value}) has to be after first_seen ({self.first_seen})')
|
||||||
|
@ -334,12 +357,16 @@ class MISPAttribute(AbstractMISP):
|
||||||
raise NewAttributeError('The value of the attribute is required.')
|
raise NewAttributeError('The value of the attribute is required.')
|
||||||
if self.type == 'datetime' and isinstance(self.value, str):
|
if self.type == 'datetime' and isinstance(self.value, str):
|
||||||
try:
|
try:
|
||||||
if '+' in self.value or '-' in self.value:
|
# Faster
|
||||||
self.value = datetime.strptime(self.value, "%Y-%m-%dT%H:%M:%S.%f%z")
|
if sys.version_info >= (3, 7):
|
||||||
elif '.' in self.value:
|
self.value = datetime.fromisoformat(self.value)
|
||||||
self.value = datetime.strptime(self.value, "%Y-%m-%dT%H:%M:%S.%f")
|
|
||||||
else:
|
else:
|
||||||
self.value = datetime.strptime(self.value, "%Y-%m-%dT%H:%M:%S")
|
if '+' in self.value or '-' in self.value:
|
||||||
|
self.value = datetime.strptime(self.value, "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
|
elif '.' in self.value:
|
||||||
|
self.value = datetime.strptime(self.value, "%Y-%m-%dT%H:%M:%S.%f")
|
||||||
|
else:
|
||||||
|
self.value = datetime.strptime(self.value, "%Y-%m-%dT%H:%M:%S")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# Slower, but if the other ones fail, that's a good fallback
|
# Slower, but if the other ones fail, that's a good fallback
|
||||||
self.value = parse(self.value)
|
self.value = parse(self.value)
|
||||||
|
@ -384,7 +411,10 @@ class MISPAttribute(AbstractMISP):
|
||||||
fs = kwargs.pop('first_seen')
|
fs = kwargs.pop('first_seen')
|
||||||
try:
|
try:
|
||||||
# Faster
|
# Faster
|
||||||
self.first_seen = datetime.strptime(fs, "%Y-%m-%dT%H:%M:%S.%f%z")
|
if sys.version_info >= (3, 7):
|
||||||
|
self.first_seen = datetime.fromisoformat(fs)
|
||||||
|
else:
|
||||||
|
self.first_seen = datetime.strptime(fs, "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
except:
|
except:
|
||||||
# Use __setattr__
|
# Use __setattr__
|
||||||
self.first_seen = fs
|
self.first_seen = fs
|
||||||
|
@ -393,7 +423,10 @@ class MISPAttribute(AbstractMISP):
|
||||||
ls = kwargs.pop('last_seen')
|
ls = kwargs.pop('last_seen')
|
||||||
try:
|
try:
|
||||||
# Faster
|
# Faster
|
||||||
self.last_seen = datetime.strptime(kwargs.pop('last_seen'), "%Y-%m-%dT%H:%M:%S.%f%z")
|
if sys.version_info >= (3, 7):
|
||||||
|
self.last_seen = datetime.fromisoformat(ls)
|
||||||
|
else:
|
||||||
|
self.last_seen = datetime.strptime(ls, "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
except:
|
except:
|
||||||
# Use __setattr__
|
# Use __setattr__
|
||||||
self.last_seen = ls
|
self.last_seen = ls
|
||||||
|
@ -647,21 +680,7 @@ class MISPObject(AbstractMISP):
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
if name in ['first_seen', 'last_seen']:
|
if name in ['first_seen', 'last_seen']:
|
||||||
if isinstance(value, datetime):
|
value = _make_datetime(value)
|
||||||
pass
|
|
||||||
elif isinstance(value, (int, float)):
|
|
||||||
# Timestamp
|
|
||||||
value = datetime.fromtimestamp(value)
|
|
||||||
elif isinstance(value, str):
|
|
||||||
value = parse(value)
|
|
||||||
elif isinstance(value, date):
|
|
||||||
value = datetime.combine(falue, datetime.min.time())
|
|
||||||
else:
|
|
||||||
raise PyMISPError(f'Invalid format for {name}: {type(value)}.')
|
|
||||||
|
|
||||||
if not value.tzinfo:
|
|
||||||
# set localtimezone if not present
|
|
||||||
value = value.astimezone()
|
|
||||||
|
|
||||||
if name == 'last_seen' and hasattr(self, 'first_seen') and self.first_seen > value:
|
if name == 'last_seen' and hasattr(self, 'first_seen') and self.first_seen > value:
|
||||||
raise PyMISPError('last_seen ({value}) has to be after first_seen ({self.first_seen})')
|
raise PyMISPError('last_seen ({value}) has to be after first_seen ({self.first_seen})')
|
||||||
|
@ -750,8 +769,11 @@ class MISPObject(AbstractMISP):
|
||||||
fs = kwargs.pop('first_seen')
|
fs = kwargs.pop('first_seen')
|
||||||
try:
|
try:
|
||||||
# Faster
|
# Faster
|
||||||
self.first_seen = datetime.strptime(fs, "%Y-%m-%dT%H:%M:%S.%f%z")
|
if sys.version_info >= (3, 7):
|
||||||
except:
|
self.first_seen = datetime.fromisoformat(fs)
|
||||||
|
else:
|
||||||
|
self.first_seen = datetime.strptime(fs, "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
|
except Exception:
|
||||||
# Use __setattr__
|
# Use __setattr__
|
||||||
self.first_seen = fs
|
self.first_seen = fs
|
||||||
|
|
||||||
|
@ -759,8 +781,11 @@ class MISPObject(AbstractMISP):
|
||||||
ls = kwargs.pop('last_seen')
|
ls = kwargs.pop('last_seen')
|
||||||
try:
|
try:
|
||||||
# Faster
|
# Faster
|
||||||
self.last_seen = datetime.strptime(kwargs.pop('last_seen'), "%Y-%m-%dT%H:%M:%S.%f%z")
|
if sys.version_info >= (3, 7):
|
||||||
except:
|
self.last_seen = datetime.fromisoformat(ls)
|
||||||
|
else:
|
||||||
|
self.last_seen = datetime.strptime(ls, "%Y-%m-%dT%H:%M:%S.%f%z")
|
||||||
|
except Exception:
|
||||||
# Use __setattr__
|
# Use __setattr__
|
||||||
self.last_seen = ls
|
self.last_seen = ls
|
||||||
|
|
||||||
|
@ -1113,7 +1138,14 @@ class MISPEvent(AbstractMISP):
|
||||||
if isinstance(value, date):
|
if isinstance(value, date):
|
||||||
pass
|
pass
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
value = parse(value).date()
|
if sys.version_info >= (3, 7):
|
||||||
|
try:
|
||||||
|
# faster
|
||||||
|
value = date.fromisoformat(fs)
|
||||||
|
except Exception:
|
||||||
|
value = parse(value).date()
|
||||||
|
else:
|
||||||
|
value = parse(value).date()
|
||||||
elif isinstance(value, (int, float)):
|
elif isinstance(value, (int, float)):
|
||||||
value = date.fromtimestamp(value)
|
value = date.fromtimestamp(value)
|
||||||
elif isinstance(value, datetime):
|
elif isinstance(value, datetime):
|
||||||
|
|
Loading…
Reference in New Issue