Skip to content

Instantly share code, notes, and snippets.

@dikderoy
Last active October 2, 2019 17:52
Show Gist options
  • Save dikderoy/93b186fcf6d3001e08c14d232097aa31 to your computer and use it in GitHub Desktop.
Save dikderoy/93b186fcf6d3001e08c14d232097aa31 to your computer and use it in GitHub Desktop.
absence.io python script to put present times automatically
import json
import logging
import os
import random
import sys
from datetime import datetime, timedelta
import attr
import mohawk
import pytz
import requests
from pytz import tzinfo, utc
from requests_hawk import HawkAuth
ABS_USER_ID = ABS_KEY_ID = os.getenv('ABS_KEY_ID')
ABS_SECRET = os.getenv('ABS_SECRET')
if not ABS_KEY_ID or not ABS_SECRET:
raise EnvironmentError('you have to provide ABS_KEY_ID and ABS_SECRET env vars')
ACTIVE_TZ = pytz.timezone('CET')
ABS_TIMESPAN_CREATE_ENDPOINT = "https://app.absence.io/api/v2/timespans/create"
logger = logging.getLogger('absence')
def basic_logging(level=logging.INFO, timed_logs=True):
log_fmt = logging.BASIC_FORMAT
if timed_logs:
log_fmt = "[%(asctime)s]:" + log_fmt
logging.basicConfig(stream=sys.stdout, format=log_fmt, level=level)
# noinspection PyProtectedMember
logging.info('logger set up with level: %s', logging._levelToName.get(level, level))
def generate_dt(h: int = 10, m: int = 0, deviation: int = 30, base_dt: datetime = None) -> datetime:
"""
generates a date from current one, which has slight deviation (under 1h interval) based on random
"""
random.seed()
assert deviation < 60, 'deviation cannot be more than an hour (59 minutes)'
m_deviation = random.randint(- deviation, + deviation)
logger.debug('gen:deviation(%s..%s): %s' % (m - deviation, m + deviation, m_deviation))
# set minutes (always plus as m_dev can be positive and negative number)
m_deviation = m + m_deviation
# assert minutes validity and adjust
if m_deviation > 59:
h += 1
m = m_deviation - 59
logger.debug('gen:over59')
elif m_deviation < 0:
h -= 1
m = 60 - abs(m_deviation)
logger.debug('gen:less00')
else:
m = m_deviation
logger.debug('gen:fits59')
logger.debug('gen:time: hh:mm | %s:%s' % (h, m))
dt = base_dt or datetime.now()
dt = dt.astimezone(ACTIVE_TZ).replace(hour=h, minute=m).astimezone(utc)
return dt
def format_dt(dt: datetime) -> str:
return dt.replace(tzinfo=None).isoformat(sep='T', timespec='milliseconds') + 'Z'
def format_tz(tz: tzinfo) -> str:
return datetime.now(tz).strftime('%z')
@attr.s(auto_attribs=True)
class AbsenceClient:
_auth: HawkAuth = None
def _get_auth(self):
if not self._auth:
self._auth = HawkAuth(id=ABS_KEY_ID, key=ABS_SECRET, algorithm='sha256')
return self._auth
def record(self, start: str, end: str) -> bool:
url = ABS_TIMESPAN_CREATE_ENDPOINT
hawk_auth = self._get_auth()
sender = mohawk.Sender(
hawk_auth.credentials,
url,
'POST',
always_hash_content=False,
)
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": sender.request_header,
}
logger.debug('record:headers:\n%s', json.dumps(headers))
body = {
"userId": ABS_USER_ID,
"start": start,
"end": end,
"timezoneName": ACTIVE_TZ.zone,
"timezone": format_tz(ACTIVE_TZ),
"type": "work"
}
logger.debug('record:headers:\n%s', body)
response = requests.post(
url,
headers=headers,
json=body)
logger.debug('record:response:\n%s', response.text)
response.raise_for_status()
return True
def run(client: AbsenceClient, dt: datetime = None):
logger.info('main:base_date: %s', dt)
start_edt = format_dt(generate_dt(10, 00, deviation=15, base_dt=dt))
logger.info('main:fab:start:%s', start_edt)
end_edt = format_dt(generate_dt(19, 00, deviation=15, base_dt=dt))
logger.info('main:fab:end:%s', end_edt)
logger.info("!!!recording!!!")
assert client.record(start_edt, end_edt) is True
logger.info("!!!done!!!")
if __name__ == '__main__':
basic_logging(level=logging.INFO)
dt_from = datetime.fromisoformat("2019-07-06T00:00:00.000+00:00")
dt_to = datetime.fromisoformat("2019-09-17T00:00:00.000+00:00")
client = AbsenceClient()
for dt in (dt_from + timedelta(days=n) for n in range((dt_to - dt_from).days + 1)):
if dt.weekday() in {5, 6}:
continue
logger.info(f'for date: {dt:%Y-%m-%d %a}')
run(client, dt)
logger.info('__ all done __')
-i https://pypi.org/simple
mohawk==1.0.0
pytz>=2019.1
requests-hawk==1.0.0
requests==2.22.0
attrs==19.1.0
@rbiersbach
Copy link

You forgot "attr" in the requirements :)

@dikderoy
Copy link
Author

dikderoy commented Oct 2, 2019

You forgot "attr" in the requirements :)

fixed =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment