123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- #!/usr/bin/python -u
- import os
- import locale
- import sys
- import getopt
- import datetime
- import time
- import json
- try:
- import MAPI
- from MAPI.Util import *
- from MAPI.Time import *
- from MAPI.Struct import *
- except ImportError as e:
- print("Not all modules can be loaded. The following modules are required:")
- print("- MAPI")
- print("")
- print(e)
- sys.exit(1)
- PR_EC_OUTOFOFFICE = PROP_TAG(PT_BOOLEAN, PR_EC_BASE+0x60)
- PR_EC_OUTOFOFFICE_MSG = PROP_TAG(PT_TSTRING, PR_EC_BASE+0x61)
- PR_EC_OUTOFOFFICE_SUBJECT = PROP_TAG(PT_TSTRING, PR_EC_BASE+0x62)
- PR_EC_OUTOFOFFICE_FROM = PROP_TAG(PT_SYSTIME, PR_EC_BASE+0x63)
- PR_EC_OUTOFOFFICE_UNTIL = PROP_TAG(PT_SYSTIME, PR_EC_BASE+0x64)
- MODE_ENABLE = 1
- MODE_DISABLE = 2
- MODE_UPDATE_ONLY = 3
- def print_help():
- print("Usage: %s -u [username of mailbox]" % sys.argv[0])
- print("")
- print("Manage out of office messages of users")
- print("")
- print("Required arguments:")
- print(" -u, --user user to set out of office message for")
- print(" -m, --mode 0 to disable out of office (default), 1 to enable")
- print("")
- print("optional arguments:")
- print(" --from specify the date/time when oof should become active")
- print(" --until specify the date/time when oof should become inactive again")
- print(" -t, --subject specify the subject to be set in oof message")
- print(" -n, --message text file containing body of out of office message")
- print(" -h, --host Host to connect with. Default: file:///var/run/kopano/server.sock")
- print(" -s, --sslkey-file SSL key file to authenticate as admin.")
- print(" -p, --sslkey-pass Password for the SSL key file.")
- print(" --dump-json Dumps the current status as JSON.")
- print(" --help Show this help message and exit.")
- print("")
- print("")
- print("Example:")
- print(" Enable out of office message of mailbox user1 with subject 'test' and body from file /tmp/oof-message")
- print(" $ %s --user user1 --mode 1 --subject 'test' --message /tmp/oof-message" % sys.argv[0])
- print("")
- print(" Enable out of office message of mailbox user1 with subject 'test' and body from file /tmp/oof-message in a multi-server-environment")
- print(" $ %s --user user1 --mode 1 --subject 'test' --message /tmp/oof-message --host https://127.0.0.1:237/ --sslkey-file /etc/kopano/ssl/client.pem --sslkey-pass password" % sys.argv[0])
- print("")
- print(" Disable out of office message of mailbox user1 in a multi-server-environment")
- print(" $ %s --user user1 --mode 0 --sslkey-file /etc/kopano/ssl/client.pem --host https://127.0.0.1:237/ --sslkey-pass password" % sys.argv[0])
- def PrintSubject(subject):
- if subject.ulPropTag == PR_EC_OUTOFOFFICE_SUBJECT:
- print("Current subject: '%s'" % subject.Value)
- else:
- print("Current subject: No subject set")
-
- def main(argv = None):
- if argv is None:
- argv = sys.argv
- try:
- opts, args = getopt.gnu_getopt(argv, "h:s:p:u:m:t:n:he", ['from=', 'until=', 'host=', 'sslkey-file=', 'sslkey-pass=', 'user=', 'mode=', 'subject=', 'message=', 'dump-json', 'help', ])
- except getopt.GetoptError as err:
- # print help information and exit:
- print(str(err))
- print("")
- print_help()
- return 1
- # defaults
- host = os.getenv("KOPANO_SOCKET", "default:")
- sslkey_file = None
- sslkey_pass = None
- mode = MODE_UPDATE_ONLY
- date_from = None
- date_until = None
- username = None
- subject = None
- message = None
- dump_json = False
-
- for o, a in opts:
- if o in ('-h', '--host'):
- host = a
- elif o in ('-s', '--sslkey-file'):
- sslkey_file = a
- elif o in ('-p', '--sslkey-pass'):
- sslkey_pass = a
- elif o in ('-u', '--user'):
- username = a
- elif o in ('-m', '--mode'):
- if a == '-':
- mode = MODE_UPDATE_ONLY
- elif a == '1':
- enabled = True
- mode = MODE_ENABLE
- else:
- enabled = False
- mode = MODE_DISABLE
- elif o == "--from":
- date_from = datetime.datetime.strptime(a, "%Y-%m-%d %H:%M")
- elif o == "--until":
- date_until = datetime.datetime.strptime(a, "%Y-%m-%d %H:%M")
- elif o in ('-t', '--subject'):
- subject = a
- elif o in ('-n', '--message'):
- message = a
- elif o == '--dump-json':
- dump_json = True
- elif o == '--help':
- print_help()
- return 0
- else:
- assert False, ("unhandled option '%s'" % o)
- if not username:
- print("No username specified.")
- print("")
- print_help()
- sys.exit(1)
- try:
- session = OpenECSession(username, '', host, sslkey_file = sslkey_file, sslkey_pass = sslkey_pass)
- except MAPIError as err:
- if err.hr == MAPI_E_LOGON_FAILED:
- print("Failed to logon. Make sure your SSL certificate is correct.")
- elif err.hr == MAPI_E_NETWORK_ERROR:
- print("Unable to connect to server. Make sure you specified the correct server.")
- else:
- print("Unexpected error occurred. hr=0x%08x" % err.hr)
- sys.exit(1)
- try:
- st = GetDefaultStore(session)
- except:
- print("Unable to open store for user '%s'" % username)
- try:
- oldstatus = st.GetProps([PR_EC_OUTOFOFFICE], 0)[0].Value
- if oldstatus == MAPI_E_NOT_FOUND:
- oldstatus = False
- except Exception:
- print("Unable to read out of office status of user '%s'" % username)
- try:
- oldsubject = st.GetProps([PR_EC_OUTOFOFFICE_SUBJECT], 0)[0].Value
- if oldsubject == MAPI_E_NOT_FOUND:
- oldsubject = None
- except Exception:
- print("Unable to read out of office subject of user '%s'" % username)
- try:
- oldmsg = st.GetProps([PR_EC_OUTOFOFFICE_MSG], 0)[0].Value
- if oldmsg == MAPI_E_NOT_FOUND:
- oldmsg = None
- except Exception:
- print("Unable to read out of office message of user '%s'" % username)
- try:
- oldfrom = st.GetProps([PR_EC_OUTOFOFFICE_FROM], 0)[0].Value
- if oldfrom == MAPI_E_NOT_FOUND:
- oldfrom = None
- else:
- oldfrom = oldfrom.datetime().isoformat()
- except Exception:
- oldfrom = None
- try:
- olduntil = st.GetProps([PR_EC_OUTOFOFFICE_UNTIL], 0)[0].Value
- if olduntil == MAPI_E_NOT_FOUND:
- olduntil = None
- else:
- olduntil = olduntil.datetime().isoformat()
- except Exception:
- olduntil = None
- if dump_json:
- result = json.dumps({
- 'set': bool(oldstatus),
- 'subject': oldsubject,
- 'message': oldmsg,
- 'from': oldfrom,
- 'until': olduntil,
- })
- print(result)
- sys.exit(0)
- if mode != MODE_UPDATE_ONLY:
- try:
- if oldstatus == enabled and not enabled:
- print("Out of office for user '%s' already disabled, skipping." % username)
- elif enabled:
- st.SetProps([SPropValue(PR_EC_OUTOFOFFICE, enabled)])
- if date_from or date_until:
- props = []
- if date_from:
- t1 = MAPI.Time.FileTime(0)
- t1.unixtime = time.mktime(date_from.timetuple())
- p1 = SPropValue(PR_EC_OUTOFOFFICE_FROM, t1)
- props.append(p1)
- if date_until:
- t2 = MAPI.Time.FileTime(0)
- t2.unixtime = time.mktime(date_until.timetuple())
- p2 = SPropValue(PR_EC_OUTOFOFFICE_UNTIL, t2)
- props.append(p2)
- st.SetProps(props)
- else:
- st.DeleteProps([PR_EC_OUTOFOFFICE_FROM, PR_EC_OUTOFOFFICE_UNTIL])
- print("Out of office enabled for user '%s'" % username)
- else:
- st.SetProps([SPropValue(PR_EC_OUTOFOFFICE, enabled)])
- print("Out of office disabled for user '%s'" % username)
- except:
- print("Unable to set out of office for user '%s'" % username)
- raise
- if mode != MODE_DISABLE:
- if date_from or date_until:
- try:
- props = []
- deleted_props = []
- if date_from:
- t1 = MAPI.Time.FileTime(0)
- t1.unixtime = time.mktime(date_from.timetuple())
- p1 = SPropValue(PR_EC_OUTOFOFFICE_FROM, t1)
- props.append(p1)
- else:
- deleted_props.append(PR_EC_OUTOFOFFICE_FROM)
- if date_until:
- t2 = MAPI.Time.FileTime(0)
- t2.unixtime = time.mktime(date_until.timetuple())
- p2 = SPropValue(PR_EC_OUTOFOFFICE_UNTIL, t2)
- props.append(p2)
- else:
- deleted_props.append(PR_EC_OUTOFOFFICE_UNTIL)
- st.DeleteProps(deleted_props)
- st.SetProps(props)
- except:
- print("Unable to update OOF date restriction for user '%s'" % username)
- raise
- if subject:
- try:
- if oldsubject == subject:
- print("Not changing subject for user '%s' as it was not updated" % username)
- else:
- print("Setting new subject '%s' for user '%s'" % (subject, username))
- st.SetProps([SPropValue(PR_EC_OUTOFOFFICE_SUBJECT, subject)])
- except:
- print("Unable to set out of office subject for user '%s'" % username)
- newsubject = st.GetProps([PR_EC_OUTOFOFFICE_SUBJECT], 0)
- PrintSubject(newsubject[0])
- if message:
- try:
- f = open(message, 'rt')
- except IOError:
- print("The specified file '%s' does not exist - Please specify a valid message file." % message)
- sys.exit(1)
- msg = f.read()
- f.close()
- try:
- if oldmsg == msg:
- print("Not updating message, already matching with input file.")
- else:
- print("Setting new out of office message for user '%s'" % username)
- st.SetProps([SPropValue(PR_EC_OUTOFOFFICE_MSG, msg)])
- except:
- print("Unable to set out of office message.")
- if __name__ == '__main__':
- locale.setlocale(locale.LC_ALL, '')
- sys.exit(main())
|