import argparse import configparser import getpass import logging import requests as requests from constants import COMING_ENTRY_CODE_ID, LEAVING_ENTRY_CODE_ID logger = logging.getLogger() logging.basicConfig(level=logging.INFO) class TimeBot: def __init__(self, baseurl: str, user: str, password: str, employee_id: str): self.logger = logging.getLogger(self.__class__.__name__) self.baseurl = baseurl self.user = user self.password = password self.employee_id = employee_id self._session = None @property def session(self): """ Return requests session object and auto login if necessary. :return: requests session :raises on any http error """ if self._session is None: self._session = requests.Session() request = self._session.get(self.baseurl + "Employee/GetEmployeeList") if 400 <= request.status_code < 500: self._login(self._session) else: request.raise_for_status() return self._session def _login(self, session): """ Obtain session cookie. :raises: on status code != 2xx """ login_data = { "username": self.user, "password": self.password, } request = session.post(self.baseurl + "Account/LogOn", data=login_data) request.raise_for_status() def add_entry(self, punch_date: str, punch_time: str, entry_code: int, note: str = None) -> requests.Response: """ Add mobatime entry. :param str punch_date: date string in format: ``DD.MM.YYYY`` :param str punch_time: time string in format: ``hh:mm`` :param int entry_code: entry type code :param str note: free text note added to the Mobatime entry :return: requests response object """ entry_data = { "periode0Date": punch_date, "periode0Time": punch_time, "selectedEntryCode": entry_code, "selectedPeriodType": 0, "employeeId": self.employee_id, } if note: entry_data["note"] = note request = self.session.post(self.baseurl + "Entry/SaveEntry", data=entry_data) return request def list_employees(self): request = self.session.get(self.baseurl + "Employee/GetEmployees") request.raise_for_status() return request.json() def punch_in(self, punch_in_date: str, punch_in_time: str): """ :param str punch_in_date: date string in format: ``DD.MM.YYYY`` :param str punch_in_time: time string in format: ``hh:mm`` :raises: on status code != 2xx """ self.add_entry(punch_in_date, punch_in_time, COMING_ENTRY_CODE_ID, note="da").raise_for_status() def punch_out(self, punch_out_date: str, punch_out_time: str): """ :param str punch_out_date: date string in format: ``DD.MM.YYYY`` :param str punch_out_time: time string in format: ``hh:mm`` :raises: on status code != 2xx """ self.add_entry(punch_out_date, punch_out_time, LEAVING_ENTRY_CODE_ID, note="weg").raise_for_status() if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("-v", help="enable debug logging", action="store_true") parser.add_argument("-u", help="mobatime login user", required=True) parser.add_argument("-i", help="mobatime employee id", required=True) parser.add_argument("-p", help="mobatime login user password", default=None) parser.add_argument("-c", help="config file", default="timebot.ini") args = parser.parse_args() if args.v: logger.setLevel(logging.DEBUG) password = args.p if password is None: password = getpass.getpass("Enter your password: ") config = configparser.ConfigParser() config.read(args.c) tb = TimeBot(baseurl=config["general"]["baseurl"], user=args.u, password=password, employee_id=args.i) tb.punch_in("23.11.2021", "09:00") tb.punch_out("23.11.2021", "18:00")