All checks were successful
continuous-integration/drone/push Build is passing
206 lines
7.0 KiB
Python
206 lines
7.0 KiB
Python
import infomentor.flock as flock
|
|
import logging
|
|
import argparse
|
|
import datetime
|
|
import sys
|
|
import os
|
|
import requests
|
|
from infomentor import db, model, connector, informer, config
|
|
|
|
|
|
logformat = (
|
|
"{asctime} - {name:25s}[{filename:20s}:{lineno:3d}] - {levelname:8s} - {message}"
|
|
)
|
|
|
|
|
|
def logtofile():
|
|
from logging.handlers import RotatingFileHandler
|
|
|
|
handler = RotatingFileHandler("log.txt", maxBytes=1024 * 1024, backupCount=10)
|
|
logging.basicConfig(
|
|
level=logging.INFO, format=logformat, handlers=[handler], style="{"
|
|
)
|
|
|
|
|
|
def logtoconsole():
|
|
logging.basicConfig(level=logging.DEBUG, format=logformat, style="{")
|
|
|
|
|
|
def parse_args(arglist):
|
|
parser = argparse.ArgumentParser(description="Infomentor Grabber and Notifier")
|
|
parser.add_argument(
|
|
"--nolog", action="store_true", help="print log instead of logging to file"
|
|
)
|
|
parser.add_argument("--username", type=str, nargs="?", help="infomentor username")
|
|
parser.add_argument("--password", type=str, nargs="?", help="infomentor password")
|
|
parser.add_argument("--fake", action="store_true", help="add fake")
|
|
parser.add_argument("--notifyerrors", action="store_true", help="add fake")
|
|
parser.add_argument("--pushover", type=str, nargs="?", help="pushover user id")
|
|
parser.add_argument("--mail", type=str, nargs="?", help="e-mail for notification")
|
|
parser.add_argument(
|
|
"--iclouduser", type=str, nargs="?", help="icloud calendar user"
|
|
)
|
|
parser.add_argument(
|
|
"--icloudpwd", type=str, nargs="?", help="icloud calendar password"
|
|
)
|
|
parser.add_argument(
|
|
"--icloudcalendar", type=str, nargs="?", help="icloud calendar calendar"
|
|
)
|
|
parser.add_argument(
|
|
"--invitationmail", type=str, nargs="?", help="e-mail for notification"
|
|
)
|
|
args = parser.parse_args(arglist)
|
|
return args
|
|
|
|
|
|
def perform_user_update(args):
|
|
username = args.username
|
|
session = db.get_db()
|
|
existing_user = (
|
|
session.query(model.User).filter(model.User.name == username).one_or_none()
|
|
)
|
|
if existing_user is not None:
|
|
logger.info("Updating user {}", username)
|
|
else:
|
|
logger.info("Creating User user {}", username)
|
|
|
|
if args.password is None:
|
|
logger.info("No password provided, asking for it")
|
|
import getpass
|
|
password = getpass.getpass(prompt="Password: ")
|
|
else:
|
|
password = args.password
|
|
|
|
if existing_user is not None:
|
|
existing_user.password = password
|
|
else:
|
|
user = model.User(name=username, password=password)
|
|
session.add(user)
|
|
|
|
if args.notifyerrors:
|
|
user.wantstatus = True
|
|
else:
|
|
user.wantstatus = False
|
|
|
|
if args.pushover is not None:
|
|
logger.info("Adding pushover notification")
|
|
user.notification = model.Notification(
|
|
ntype=model.Notification.Types.PUSHOVER, info=args.pushover
|
|
)
|
|
elif args.mail:
|
|
logger.info("Adding email notification")
|
|
user.notification = model.Notification(
|
|
ntype=model.Notification.Types.EMAIL, info=args.mail
|
|
)
|
|
elif args.fake:
|
|
logger.info("Adding fake notification")
|
|
user.notification = model.Notification(
|
|
ntype=model.Notification.Types.FAKE, info=""
|
|
)
|
|
|
|
if (
|
|
args.iclouduser is not None
|
|
and args.icloudpwd is not None
|
|
and args.icloudcalendar is not None
|
|
):
|
|
logger.info("Adding icloud calendar")
|
|
user.icalendar = model.ICloudCalendar(
|
|
icloud_user=args.iclouduser,
|
|
password=args.icloudpwd,
|
|
calendarname=args.icloudcalendar,
|
|
)
|
|
|
|
if args.invitationmail:
|
|
logger.info("Activating sending of calendar entries per mail")
|
|
user.invitation = model.Invitation(email=mail)
|
|
|
|
session.commit()
|
|
|
|
|
|
def notify_users():
|
|
logger = logging.getLogger(__name__)
|
|
session = db.get_db()
|
|
cfg = config.load()
|
|
if cfg["healthchecks"]["url"] != "":
|
|
logger.info("Triggering Healthcheck Start")
|
|
requests.get(cfg["healthchecks"]["url"] + "/start")
|
|
|
|
for user in session.query(model.User):
|
|
logger.info("==== USER: %s =====", user.name)
|
|
if user.password == "":
|
|
logger.warning("User %s not enabled", user.name)
|
|
continue
|
|
now = datetime.datetime.now()
|
|
im = connector.Infomentor(user.name)
|
|
im.login(user.password)
|
|
logger.info("User loggedin")
|
|
statusinfo = {"datetime": now, "ok": False, "info": "", "degraded_count": 0}
|
|
if user.apistatus is None:
|
|
user.apistatus = model.ApiStatus(**statusinfo)
|
|
logger.info("Former API status: %s", user.apistatus)
|
|
try:
|
|
i = informer.Informer(user, im, logger=logger)
|
|
i.update_news()
|
|
i.update_homework()
|
|
i.update_calendar()
|
|
statusinfo["ok"] = True
|
|
statusinfo["degraded"] = False
|
|
except Exception as e:
|
|
inforstr = "Exception occured:\n{}:{}\n".format(type(e).__name__, e)
|
|
statusinfo["ok"] = False
|
|
statusinfo["info"] = inforstr
|
|
logger.exception("Something went wrong")
|
|
finally:
|
|
if user.apistatus.ok == True and statusinfo["ok"] == False:
|
|
logger.error("Switching to degraded state %s", user.name)
|
|
statusinfo["degraded_count"] = 1
|
|
if user.apistatus.ok == False and statusinfo["ok"] == False:
|
|
if user.apistatus.degraded_count == 1 and user.wantstatus:
|
|
im.send_status_update(statusinfo["info"])
|
|
try:
|
|
statusinfo["degraded_count"] = user.apistatus["degraded_count"] + 1
|
|
except Exception as e:
|
|
statusinfo["degraded_count"] = 1
|
|
if user.apistatus.ok == False and statusinfo["ok"] == True:
|
|
statusinfo["info"] = "Works as expected, failed {} times".format(
|
|
user.apistatus.degraded_count
|
|
)
|
|
statusinfo["degraded_count"] = 0
|
|
if user.wantstatus:
|
|
im.send_status_update(statusinfo["info"])
|
|
user.apistatus.updateobj(statusinfo)
|
|
logger.info("New API status: %s", user.apistatus)
|
|
session.commit()
|
|
|
|
if cfg["healthchecks"]["url"] != "":
|
|
logger.info("Triggering Healthcheck Stop")
|
|
requests.get(cfg["healthchecks"]["url"])
|
|
|
|
|
|
def main():
|
|
args = parse_args(sys.argv[1:])
|
|
if args.nolog:
|
|
logtoconsole()
|
|
else:
|
|
logtofile()
|
|
logger = logging.getLogger("Infomentor Notifier")
|
|
logger.info("STARTING-------------------- %s", os.getpid())
|
|
try:
|
|
lock = flock.flock()
|
|
if not lock.aquire():
|
|
logger.info("EXITING - PREVIOUS IS STILL RUNNING")
|
|
raise Exception()
|
|
if args.username:
|
|
perform_user_update(args)
|
|
else:
|
|
notify_users()
|
|
except Exception as e:
|
|
logger.info("Exceptional exit")
|
|
logger.exception("Info")
|
|
finally:
|
|
logger.info("EXITING--------------------- %s", os.getpid())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|