|
|
|
@ -0,0 +1,118 @@ |
|
|
|
|
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") |