* feat(api): dynamic-api 1/2
* feat(api): dynamic-api 2/2
feat(api): core-api 1/2
* feat(api): changed schemas
feat(api): aipkey authorizer
feat(api): jwt authorizer payload
feat(api): core-api 2/3
* feat(api): apikey authorizer
feat(api): shared context
feat(api): response editor
feat(api): middleware
feat(api): custom router
feat(api): fix auth double call
* feat(api): dashboard
feat(api): insights
feat(api): public api v1
* feat(api): allow full CORS
* feat(api): use decouple-config instead of env
feat(api): fixed conflict slack endpoint
feat(api): fixed favorite errors param
* feat(api): migration fixes
* feat(api): changes
* feat(api): crons
* feat(api): changes and fixes
* feat(api): added new endpoints
feat(api): applied new changes
feat(api): Docker image
* feat(api): EE 1/4
* feat(api): EE core_dynamic
* feat(api): global routers generator
* feat(api): project authorizer
feat(api): docker image
feat(api): crons
* feat(api): EE trace activity
* feat(api): changed ORRouter
* feat(api): EE trace activity parameters&payload
* feat(api): EE trace activity action name & path_format
* feat(db): user trace
* feat(api): EE trace activity ignore routes and hide attribute
feat(api): fix funnel payload schema
* feat(api): mobile support
* feat(api): changed build script
* feat(api): changed mobile sign endpoint
feat(api): changed requirements.txt
* feat(api): changed dockerfile
* feat(api): changed mobile-env-var
* feat(api): removed insights
* feat(api): changed EE Dockerfile
* feat(api): cast session_id to str for signing
* feat(api): fixed error_id type
* feat(api): fixed /errors priority conflict
* feat(api): fixed /errors/{errorId} default params
* feat(api): fixed change password after invitation
* feat(api): use background task for emails instead of low-timeout-api
feat(api): EE fixed missing required params
* feat(api): funnel-insights payload change
* feat(api): funnel-insights payload change
* feat(api): changed edit user payload schema
* feat(api): changed metrics payload schema
* feat(api): changed metrics payload schema
* feat(api): changed edit user default values
feat(api): fixed change error status route
* feat(api): changed edit user
* feat(api): stop user from changing his own role
* feat(api): changed add slack
* feat(api): changed get funnel
* feat(api): changed get funnel on the fly payload
feat(api): changed update payload
* feat(api): changed get funnel on the fly payload
* feat(api): changed update funnel payload
* feat(api): changed get funnel-sessions/issues on the fly payload
* feat(api): fixed funnel missing rangeValue
* feat(api): fixes
* feat(api): iceServers configuration
* feat(api): fix issueId casting
* feat(api): changed issues-sessions endpoint payload-schema
* feat(api): EE changed traces-ignored-routes
* feat(api): EE include core sessions.py
* feat(api): EE check licence on every request if expired
* feat(api): move general stats to dynamic
* feat(api): code cleanup
feat(api): removed sentry
* feat(api): changed traces-ignore-routes
* feat(api): changed dependencies
* feat(api): changed jwt-auth-response code
* feat(api): changed traces-ignore-routes
* feat(api): changed traces-ignore-routes
* feat(api): removed PyTZ
feat(api): migrated time-helper to zoneinfo
* feat(api): EE added missing dependency
feat(api): changed base docker image
* feat(api): merge after roles
* feat(api): EE roles fastapi
* feat(db): handel HTTPExceptions
* feat(db): changed payload schema
* feat(db): changed payload schema
* feat(api): included insights
* feat(api): removed unused helper
* feat(api): merge from dev to fatsapi
* feat(api): merge fixes
feat(api): SAML migration
* feat(api): changed GET /signup response
feat(api): changed EE Dockerfile
* feat(api): changed edition detection
* feat(api): include ee endpoints
* feat(api): add/edit member changes
* feat(api): saml changed redirect
* feat(api): track session's replay
feat(api): track error's details
* feat(api): ignore tracking for read roles
* feat(api): define global queue
feat(api): define global scheduler
feat(api): traces use queue
feat(api): traces batch insert
feat(DB): changed traces schema
* feat(api): fix signup captcha
* feat(api): fix signup captcha
* feat(api): optional roleId
feat(api): set roleId to member if None
* feat(api): fixed edit role
* feat(api): return role details when creating a new member
* feat(api): trace: use BackgroundTasks instead of BackgroundTask to not override previous tasks
* feat(api): trace: use BackgroundTask if no other background task is defined
* feat(api): optimised delete metadata
* feat(api): Notification optional message
* feat(api): fix background-task reference
* feat(api): fix trace-background-task
* feat(api): fixed g-captcha for reset password
* feat(api): fix edit self-user
* feat(api): fixed create github-issue
* feat(api): set misfire_grace_time for crons
* feat(api): removed chalice
feat(api): freeze dependencies
* feat(api): refactored blueprints
* feat(api): /metadata/session_search allow projectId=None
* feat(api): public API, changed userId type
* feat(api): fix upload sourcemaps
* feat(api): user-trace support ApiKey endpoints
* feat(api): fixed user-trace foreign key type
* feat(api): fixed trace schema
* feat(api): trace save auth-method
* feat(api): trace fixed auth-method
* feat(api): trace changed schema
134 lines
5.9 KiB
Python
134 lines
5.9 KiB
Python
from calendar import monthrange
|
|
from datetime import datetime, timedelta
|
|
|
|
import zoneinfo
|
|
|
|
UTC_ZI = zoneinfo.ZoneInfo("UTC")
|
|
|
|
|
|
class TimeUTC:
|
|
MS_MINUTE = 60 * 1000
|
|
MS_HOUR = MS_MINUTE * 60
|
|
MS_DAY = MS_HOUR * 24
|
|
MS_WEEK = MS_DAY * 7
|
|
MS_MONTH = MS_DAY * 30
|
|
MS_MONTH_TRUE = monthrange(datetime.now(UTC_ZI).astimezone(UTC_ZI).year,
|
|
datetime.now(UTC_ZI).astimezone(UTC_ZI).month)[1] * MS_DAY
|
|
RANGE_VALUE = None
|
|
|
|
@staticmethod
|
|
def midnight(delta_days=0):
|
|
return int((datetime.now(UTC_ZI) + timedelta(delta_days)) \
|
|
.replace(hour=0, minute=0, second=0, microsecond=0) \
|
|
.astimezone(UTC_ZI).timestamp() * 1000)
|
|
|
|
@staticmethod
|
|
def __now(delta_days=0, delta_minutes=0, delta_seconds=0):
|
|
return (datetime.now(UTC_ZI) + timedelta(days=delta_days, minutes=delta_minutes, seconds=delta_seconds)) \
|
|
.astimezone(UTC_ZI)
|
|
|
|
@staticmethod
|
|
def now(delta_days=0, delta_minutes=0, delta_seconds=0):
|
|
return int(TimeUTC.__now(delta_days=delta_days, delta_minutes=delta_minutes,
|
|
delta_seconds=delta_seconds).timestamp() * 1000)
|
|
|
|
@staticmethod
|
|
def month_start(delta_month=0):
|
|
month = TimeUTC.__now().month + delta_month
|
|
return int(datetime.now(UTC_ZI) \
|
|
.replace(year=TimeUTC.__now().year + ((-12 + month) // 12 if month % 12 <= 0 else month // 12),
|
|
month=12 + month % 12 if month % 12 <= 0 else month % 12 if month > 12 else month,
|
|
day=1,
|
|
hour=0, minute=0,
|
|
second=0,
|
|
microsecond=0) \
|
|
.astimezone(UTC_ZI).timestamp() * 1000)
|
|
|
|
@staticmethod
|
|
def year_start(delta_year=0):
|
|
return int(datetime.now(UTC_ZI) \
|
|
.replace(year=TimeUTC.__now().year + delta_year, month=1, day=1, hour=0, minute=0, second=0,
|
|
microsecond=0) \
|
|
.astimezone(UTC_ZI).timestamp() * 1000)
|
|
|
|
@staticmethod
|
|
def custom(year=None, month=None, day=None, hour=None, minute=None):
|
|
args = locals()
|
|
return int(datetime.now(UTC_ZI) \
|
|
.replace(**{key: args[key] for key in args if args[key] is not None}, second=0, microsecond=0) \
|
|
.astimezone(UTC_ZI).timestamp() * 1000)
|
|
|
|
@staticmethod
|
|
def future(delta_day, delta_hour, delta_minute, minutes_period=None, start=None):
|
|
this_time = TimeUTC.__now()
|
|
if delta_day == -1:
|
|
if this_time.hour < delta_hour or this_time.hour == delta_hour and this_time.minute < delta_minute:
|
|
return TimeUTC.custom(hour=delta_hour, minute=delta_minute)
|
|
|
|
return TimeUTC.custom(day=TimeUTC.__now(1).day, hour=delta_hour, minute=delta_minute)
|
|
elif delta_day > -1:
|
|
if this_time.weekday() < delta_day or this_time.weekday() == delta_day and (
|
|
this_time.hour < delta_hour or this_time.hour == delta_hour and this_time.minute < delta_minute):
|
|
return TimeUTC.custom(day=TimeUTC.__now(delta_day - this_time.weekday()).day, hour=delta_hour,
|
|
minute=delta_minute)
|
|
|
|
return TimeUTC.custom(day=TimeUTC.__now(7 + delta_day - this_time.weekday()).day, hour=delta_hour,
|
|
minute=delta_minute)
|
|
if start is not None:
|
|
return start + minutes_period * 60 * 1000
|
|
|
|
return TimeUTC.now(delta_minutes=minutes_period)
|
|
|
|
@staticmethod
|
|
def from_ms_timestamp(ts):
|
|
return datetime.fromtimestamp(ts // 1000, UTC_ZI)
|
|
|
|
@staticmethod
|
|
def to_human_readable(ts, fmt='%Y-%m-%d %H:%M:%S UTC'):
|
|
return datetime.utcfromtimestamp(ts // 1000).strftime(fmt)
|
|
|
|
@staticmethod
|
|
def human_to_timestamp(ts, pattern):
|
|
return int(datetime.strptime(ts, pattern).timestamp() * 1000)
|
|
|
|
@staticmethod
|
|
def datetime_to_timestamp(date):
|
|
if date is None:
|
|
return None
|
|
return int(datetime.timestamp(date) * 1000)
|
|
|
|
@staticmethod
|
|
def get_start_end_from_range(range_value):
|
|
range_value = range_value.upper()
|
|
if TimeUTC.RANGE_VALUE is None:
|
|
this_instant = TimeUTC.now()
|
|
TimeUTC.RANGE_VALUE = {
|
|
"TODAY": {"start": TimeUTC.midnight(), "end": this_instant},
|
|
"YESTERDAY": {"start": TimeUTC.midnight(delta_days=-1), "end": TimeUTC.midnight()},
|
|
"LAST_7_DAYS": {"start": TimeUTC.midnight(delta_days=-7), "end": this_instant},
|
|
"LAST_30_DAYS": {"start": TimeUTC.midnight(delta_days=-30), "end": this_instant},
|
|
"THIS_MONTH": {"start": TimeUTC.month_start(), "end": this_instant},
|
|
"LAST_MONTH": {"start": TimeUTC.month_start(delta_month=-1), "end": TimeUTC.month_start()},
|
|
"THIS_YEAR": {"start": TimeUTC.year_start(), "end": this_instant},
|
|
"CUSTOM_RANGE": {"start": TimeUTC.midnight(delta_days=-7), "end": this_instant} # Default is 7 days
|
|
}
|
|
return TimeUTC.RANGE_VALUE[range_value]["start"], TimeUTC.RANGE_VALUE[range_value]["end"]
|
|
|
|
@staticmethod
|
|
def get_utc_offset():
|
|
return int((datetime.now(UTC_ZI).now() - datetime.now(UTC_ZI).replace(tzinfo=None)).total_seconds() * 1000)
|
|
|
|
@staticmethod
|
|
def trunc_day(timestamp):
|
|
dt = TimeUTC.from_ms_timestamp(timestamp)
|
|
return TimeUTC.datetime_to_timestamp(dt
|
|
.replace(hour=0, minute=0, second=0, microsecond=0)
|
|
.astimezone(UTC_ZI))
|
|
|
|
@staticmethod
|
|
def trunc_week(timestamp):
|
|
dt = TimeUTC.from_ms_timestamp(timestamp)
|
|
start = dt - timedelta(days=dt.weekday())
|
|
return TimeUTC.datetime_to_timestamp(start
|
|
.replace(hour=0, minute=0, second=0, microsecond=0)
|
|
.astimezone(UTC_ZI))
|