allow savin of session cookies

master
Maximilian Zettler 4 years ago
parent ecb94baaf3
commit ec3372de0d
  1. 1
      .gitignore
  2. 71
      timebot.py

1
.gitignore vendored

@ -2,3 +2,4 @@ venv/
timebot.ini timebot.ini
__pycache__/ __pycache__/
.idea/ .idea/
.kekse

@ -3,6 +3,7 @@ import configparser
import datetime import datetime
import getpass import getpass
import logging import logging
import pickle
import sys import sys
import requests as requests import requests as requests
@ -16,11 +17,14 @@ logging.basicConfig(level=logging.INFO)
class TimeBot: class TimeBot:
def __init__(self, baseurl: str, user: str, password: str): def __init__(self, baseurl: str, user: str, password: str = None, ask_for_password: bool = False,
save_session: bool = False):
self.logger = logging.getLogger(self.__class__.__name__) self.logger = logging.getLogger(self.__class__.__name__)
self.baseurl = self._sanitize_baseurl(baseurl) self.baseurl = self._sanitize_baseurl(baseurl)
self.user = user self.user = user
self.password = password self.password = password
self._ask_for_password = ask_for_password
self._save_session = save_session
self._session = None self._session = None
self._current_user = None self._current_user = None
@ -40,19 +44,29 @@ class TimeBot:
""" """
if self._session is None: if self._session is None:
self._session = requests.Session() self._session = requests.Session()
try:
self._load_session_cookies(self._session)
except FileNotFoundError as e:
self.logger.error(e)
raise
request = self._session.get(self.baseurl + "Employee/GetEmployeeList") request = self._session.get(self.baseurl + "Employee/GetEmployeeList")
if 400 <= request.status_code < 500: if 400 <= request.status_code < 500:
self._login(self._session) self._login(self._session)
self._save_session_cookies(self._session)
else: else:
request.raise_for_status() request.raise_for_status()
return self._session return self._session
def _login(self, session): def _login(self, session: requests.Session):
""" """
Obtain session cookie. Obtain session cookie.
:raises: on status code != 2xx :raises: on status code != 2xx
""" """
if self.password is None and self._ask_for_password:
self.password = self._get_password()
else:
raise Exception("could not obtain password")
login_data = { login_data = {
"username": self.user, "username": self.user,
"password": self.password, "password": self.password,
@ -60,6 +74,35 @@ class TimeBot:
request = session.post(self.baseurl + "Account/LogOn", data=login_data) request = session.post(self.baseurl + "Account/LogOn", data=login_data)
request.raise_for_status() request.raise_for_status()
@staticmethod
def _get_password():
"""
Ask the user for his password.
:return: the users password
"""
return getpass.getpass("Enter your password: ")
def _save_session_cookies(self, session: requests.Session):
"""
Save the session cookies as pickle file.
:param requests.Session session: the requests session to extract the cookies from
"""
with open(".kekse", "wb") as f:
if self._save_session:
pickle.dump(requests.utils.dict_from_cookiejar(session.cookies), f)
def _load_session_cookies(self, session: requests.Session):
"""
Load the session cookies from the pickle file and updates the given session.
:param requests.Session session: the requests session which will be updated with the loaded cookies
"""
with open(".kekse", "rb") as f:
if self._save_session:
session.cookies.update(requests.utils.cookiejar_from_dict(pickle.load(f)))
def add_entry(self, punch_datetime: datetime.datetime, entry_code: int, note: str = None) -> requests.Response: def add_entry(self, punch_datetime: datetime.datetime, entry_code: int, note: str = None) -> requests.Response:
""" """
Add mobatime entry. Add mobatime entry.
@ -191,6 +234,7 @@ if __name__ == '__main__':
parser.add_argument("-u", help="mobatime login user", required=True) parser.add_argument("-u", help="mobatime login user", required=True)
parser.add_argument("-p", help="mobatime login user password", default=None) parser.add_argument("-p", help="mobatime login user password", default=None)
parser.add_argument("-c", help="config file", default="timebot.ini") parser.add_argument("-c", help="config file", default="timebot.ini")
parser.add_argument("--save-cookies", help="save auth cookies to `./.kekse`", action="store_true", default=False)
subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name') subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name')
# subparser command: `punch` # subparser command: `punch`
@ -200,7 +244,8 @@ if __name__ == '__main__':
help=f"type of time entry; this can be {', '.join(PUNCH_COMMANDS)}", help=f"type of time entry; this can be {', '.join(PUNCH_COMMANDS)}",
default="punch_in", default="punch_in",
choices=PUNCH_COMMANDS) choices=PUNCH_COMMANDS)
parser_punch.add_argument("-s", help=f"timestamp in format `{SIMPLE_DATETIME_FORMAT_HUMAN}` or `now`", default="now") parser_punch.add_argument("-s", help=f"timestamp in format `{SIMPLE_DATETIME_FORMAT_HUMAN}` or `now`",
default="now")
# subparser command: `list-entries` # subparser command: `list-entries`
parser_list_entries = subparsers.add_parser("list-entries", help="use this command to list your time entries") parser_list_entries = subparsers.add_parser("list-entries", help="use this command to list your time entries")
@ -225,14 +270,11 @@ if __name__ == '__main__':
if args.v: if args.v:
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
password = args.p
if password is None:
password = getpass.getpass("Enter your password: ")
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read(args.c) config.read(args.c)
tb = TimeBot(baseurl=config["general"]["baseurl"], user=args.u, password=password) tb = TimeBot(baseurl=config["general"]["baseurl"], user=args.u, password=args.p, ask_for_password=args.save_cookies,
save_session=True)
if args.subparser_name == "punch": if args.subparser_name == "punch":
if args.s == "now": if args.s == "now":
punch_datetime = datetime.datetime.now() punch_datetime = datetime.datetime.now()
@ -249,16 +291,16 @@ if __name__ == '__main__':
last_punch = tb.get_entries(1, now.replace(hour=0, minute=0, second=0, microsecond=0)) last_punch = tb.get_entries(1, now.replace(hour=0, minute=0, second=0, microsecond=0))
method = None method = None
if not last_punch: if not last_punch:
logger.info("could not detect any time entry for today... punching in") logger.debug("could not detect any time entry for today... punching in")
method = "punch_in" method = "punch_in"
elif last_punch[0]["entryNumber"] == COMING_ENTRY_CODE_ID: elif last_punch[0]["entryNumber"] == COMING_ENTRY_CODE_ID:
logger.info("your last entry was `punch_in`... starting break") logger.debug("your last entry was `punch_in`... starting break")
method = "break_start" method = "break_start"
elif last_punch[0]["entryNumber"] == BREAK_START_ENTRY_CODE_ID: elif last_punch[0]["entryNumber"] == BREAK_START_ENTRY_CODE_ID:
logger.info("your last entry was `break_start`... ending break") logger.debug("your last entry was `break_start`... ending break")
method = "break_end" method = "break_end"
elif last_punch[0]["entryNumber"] == BREAK_END_ENTRY_CODE_ID: elif last_punch[0]["entryNumber"] == BREAK_END_ENTRY_CODE_ID:
logger.info("your last entry was `break_end`... punching out") logger.debug("your last entry was `break_end`... punching out")
method = "punch_out" method = "punch_out"
elif last_punch[0]["entryNumber"] == LEAVING_ENTRY_CODE_ID: elif last_punch[0]["entryNumber"] == LEAVING_ENTRY_CODE_ID:
logger.error("your last entry was `punch_out`... punching in again with this command is not supported") logger.error("your last entry was `punch_out`... punching in again with this command is not supported")
@ -267,6 +309,11 @@ if __name__ == '__main__':
logger.error("hit an unknown situation... detection failed; run with `-v` for more info") logger.error("hit an unknown situation... detection failed; run with `-v` for more info")
logger.debug(f"last entry was: {last_punch}") logger.debug(f"last entry was: {last_punch}")
exit(1) exit(1)
logger.info("running `{}` with date `{}` and time `{}`".format(
method,
now.strftime(SIMPLE_DATE_FORMAT),
now.strftime(SIMPLE_TIME_FORMAT),
))
getattr(tb, method)(now) getattr(tb, method)(now)
elif args.subparser_name == "list-entries": elif args.subparser_name == "list-entries":
end_date = None end_date = None

Loading…
Cancel
Save