#!/usr/bin/python
# ^^^^^^^ PATH TO PYTHON.  Not tested on 3.x.
import pwd, time, os, sys, smtplib
from email.mime.text import MIMEText
global debug, dpath

# VISONIC ALARM RECEIVER
# Put in /scripts/ on your web server running on port 8080 and point your panel to it's IP.
# Quick and dirty implementation without needing non-standard libs. Should work out of the box with a standard install of Apache and Python on Windows or *nix
# It's not pretty if you want to re-write it and make it nice be my guest.
# If you are getting a com error make a file called /scripts/update.php with the following text "status =0&ka_time =480&allow =0&id =119254&"
# I take no responsibility for the use of this script in replacement for the official manufacturers software
# and make no guarantees about it's compatibility or reliability USE AT YOUR OWN RISK!
# Coded by Guyfromhe on ShieldLab

######################

DRYRUNTEST=False
#Configuration:
paneltime = 0		# 0 - Use server time. 1 - Use panel time sent in timestamp
months = ['Zero Padded','January','Febuary','March','April','May','June','July','August','September','October','November','December']	# Month names.  First entry will never be used but must be there!
debug = 0	# 1 - Enable debug raw data log  0 - Don't log raw data
dpath = "/var/visonic"	# Path for debug files no trailing slash
semail = 1	# 1 - Enable e-mail 	0 - log to e-mail file
edefault='luca.malgeri@cern.ch'	# Default e-mail address when not specified by panel. Blank to just drop messages
efrom = 'malgeri.home@gmail.com'	# From address
subject = "Event detected from Visonic alarm system!"	# Subject for e-mail
eserver = "smtp.gmail.com"	# Outgoing mail server on port 25 (does not support auth or ssl)
eport = 587
epasswd = "Tremiti1"

# Security:
secmode = 0	# 0 - No security   1 - Match Account  2 - Match Serial   3 - Match Both
valid_accounts = ['000000',"001234"] # List of valid accounts 'account #','account #', etc
valid_serials = ['111111','222222']   # List of valid serial numbers, same format as above
##################################################################################################



def email(edefault, efrom, subject, eserver, elist,body):
	global debug, dpath
	if elist== "" or elist == "\n": elist = edefault
	elist = elist.split('\n')


	for addy in elist:
		if addy != "":
			# Create a text/plain message
			msg = MIMEText(body)
			msg['Subject'] = subject
			msg['From'] = efrom
			msg['To'] = addy
	
			s = smtplib.SMTP(eserver,eport)
			s.ehlo()
			s.starttls()
			s.login(efrom,epasswd)
			s.sendmail(efrom, addy, msg.as_string())
			s.close()
			# s.quit()
			if debug == 1:
				q = open("%s/email-debug.txt" % dpath,'a')
				q.write(efrom +" "+addy +" "+ body+"\n")
				q.close()


# ip = cgi.escape(os.environ["REMOTE_ADDR"])  # get thar IP
ip = sys.argv[1]  # get thar IP

# generate header
#print "Content type: text/html\n\n"
#print "<br> test <br>"
print "argument= "+sys.argv[2]

if not DRYRUNTEST:
#	form = cgi.FieldStorage()

# Doesn't actually post a real form, just posts XML data. Work on the full string for ease
	data = sys.argv[2]
else:
	data="""
<?xml version='1 0'?>
 <notify>
  <pmax_account>001234</pmax_account>
  <index>39</index>
  <serial>0208018292</serial>
  <time>87765</time>
  <priority>2</priority>
  <event id='81' type='Arm Home'/>
  <profile id='3'  type='Open / Close'/>
  <device id='3' type='User'/>
  <location id='1' type='Admin'/>
  <zone id='-1'/>
  <userlist>
  </userlist>
 </notify>
"""

data = data.replace('"',"'")

data = data.split('\n')


# Initialize the user list
userlist = {}
elist = ""

# Turn all the XML crap into variables. This seems to be pretty standardized/simple format.
if debug == 1:
	z = open('%s/XMLdata.txt' % dpath,'a')


for line in data:
	print "LINE:",line
	if debug == 1:
		z.write(line + "\n")
	try:
		if line.find('<pmax_account') != -1: account = line.split('>')[1].split('<')[0]
		if line.find('<index') != -1: index = line.split('>')[1].split('<')[0]
		if line.find('<serial') != -1: serial = line.split('>')[1].split('<')[0]
		if line.find('<time') != -1: epoch = float(line.split('>')[1].split('<')[0])*1.0
		if line.find('<priority') != -1: prio = line.split('>')[1].split('<')[0]
		if line.find('<partition') != -1: partition = line.split('>')[1].split('<')[0]
		if line.find('<forward_automation') != -1: fw_auto = line.split('>')[1].split('<')[0]

		if line.find("<event id='") != -1: 
			eid = line.split("'")[1]
			etype = line.split("type='")[1].split("'")[0]

		if line.find("<profile id='") != -1: 
			pid = line.split("'")[1]
			ptype = line.split("type='")[1].split("'")[0]

		if line.find("<device id='") != -1: 
			did = line.split("'")[1]
			dtype = line.split("type='")[1].split("'")[0]

		if line.find("<location id='") != -1: 
			lid = line.split("'")[1]
			ltype = line.split("type='")[1].split("'")[0]

		if line.find("<zone id='") != -1: 
			zid = line.split("'")[1]

		if line.find("<user name='") != -1: 
			userlist[line.split("'")[1]] = {}
			userlist[line.split("'")[1]]['email'] = line.split("email='")[1].split("'")[0]
			userlist[line.split("'")[1]]['phone'] = line.split("phone='")[1].split("'")[0]
			userlist[line.split("'")[1]]['is_sms'] = line.split("is_sms='")[1].split("'")[0]
			userlist[line.split("'")[1]]['is_mms'] = line.split("is_mms='")[1].split("'")[0]
			userlist[line.split("'")[1]]['is_email'] = line.split("is_email='")[1].split("'")[0]

	except:
		pass

#See if we are using server time or sent timestamp and make it into a strtime
if paneltime == 1:
	epoch = time.gmtime(epoch)
else:
	epoch = time.localtime()

# Create the time stamp in the requested format
timestamp = str(epoch[3])+":"+str(epoch[4])+" " + months[epoch[1]]+ " " + str(epoch[2]) + " " + str(epoch[0])


for user in userlist:
	if userlist[user]['is_email'] == "1": elist += userlist[user]['email']+"\n"

if debug == 1:
	z.close() # close the data file

#print "<br> username="+pwd.getpwuid(os.getuid()).pw_name 
#Generate the actual message
f = open('%s/e-mail.txt' % dpath,'a')


if secmode != 0:
	if secmode == 1:
		# if not valid account end session
		OK = 0
		for i in valid_accounts:
			if i == account: OK =1
		if OK == 0:
			f.write(str(ip) + " " + str(account) + " " + str(serial) + " Access Denied!\n")
			f.close()
			print "Access Denied!"
			sys.exit(0)
	if secmode == 2:
		# if not valid serial end session
		OK = 0
		for i in valid_serials:
			if i == serial: OK =1
		if OK == 0:
			f.write(str(ip) + " " + str(account) + " " + str(serial) + " Access Denied!\n")
			f.close()
			print "Access Denied!"
			sys.exit(0)
	if secmode == 3:
		# if not valid serial&account end session
		OK = 0
		for i in valid_accounts:
			if i == account: OK =1
		if OK == 0:
			f.write(str(ip) + " " + str(account) + " " + str(serial) + " Access Denied!\n")
			f.close()
			print "Access Denied!"
			sys.exit(0)

		OK = 0
		for i in valid_serials:
			if i == serial: OK =1
		if OK == 0:
			f.write(str(ip) + " " + str(account) + " " + str(serial) + " Access Denied!\n")
			f.close()
			print "Access Denied!"
			sys.exit(0)


# Where we wouls send the e-mail

if dtype != "User":
	if semail == 1:
		body = etype + " detected in zone " + zid + " (" + ltype + "). " + timestamp+"\n\n"
		print "Sending email"
		email(edefault, efrom, subject, eserver,elist, body)
		print "Email sent"		
	else:
		f.write(elist+etype + " detected in zone " + zid + " (" + ltype + "). " + timestamp+"\n\n")
else:
	if semail == 1:
		body = etype + " detected by user " + zid + " (" + ltype + "). " + timestamp+"\n\n"
		print "Sending email"
		email(edefault, efrom, subject, eserver, elist, body)
		print "Email sent"
	else:
		f.write(elist+etype + " detected by user " + zid + " (" + ltype + "). " + timestamp+"\n\n")

f.close()




print "status =0&ka_time =480&allow =0&id =119254&"
