# ex:ts=4
#
# logpacket
#   -- coolwater log centre packet library
#
# $LinuxKorea: logpacket.py,v 1.2 2001/11/26 07:54:52 perky Exp $
#
# Copyright 2001 Hye-Shik Chang. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of author nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE. 
#
# code by Hye-Shik Chang <perky@linuxkorea.co.kr>
#

from time import time
from struct import calcsize, pack, unpack
# for 1.6 and under
spack = pack
sunpack = unpack
del pack, unpack

FMT = "LLHBBL"
FMT_SIZE = calcsize(FMT)

(	TYPE_NOTICE,
	TYPE_WARNING,
	TYPE_ACCESS,
	TYPE_ERROR,
	TYPE_FATAL,
	TYPE_PERIODIC,
	TYPE_STAT		) = range(7)

class LogPacket:
	"""CoolWater LogPacket Container"""
	def __init__(self, pkt=None, autostamp=1):
		self.autostamp = autostamp
		if pkt is not None:
			self.parse(pkt)
		else:
			self.timestamp, self.pid, self.mid, self.type, self.loglevel, self.reserved = 0,0,0,0,0,0
			self.data = ''
	
	def parse(self, pkt):
		if len(pkt) < FMT_SIZE:
			raise ValueError, "Unexpected packet end on LogPacket"
		self.timestamp, self.pid, self.mid, self.type, self.loglevel, self.reserved \
															= sunpack(FMT, pkt[:FMT_SIZE])
		self.data = pkt[FMT_SIZE:]
	
	def __call__(self):
		if self.autostamp:
			self.timestamp = int(time())
		return spack(FMT, self.timestamp, self.pid, self.mid, self.type, self.loglevel,
														self.reserved) + self.data

def unpack(pkt):
	return LogPacket(pkt)

def pack(ts, pid, mid, type, loglevel, data):
	l = LogPacket()
	l.timestamp	= ts
	l.pid		= pid
	l.mid		= mid
	l.type		= type
	l.loglevel	= loglevel
	l.data		= data
	return l()

if __name__ == '__main__':
	import os

	pkt = '\xe2\x7f\xef\x05\xe8-\x01\x00?\x00\x05\x00\x00\x00\x00\x00GET / HTTP/1.0'
	info = unpack(pkt)
	print info.timestamp, info.type, info.loglevel, info.mid, info.pid
	print info.data

	k = LogPacket()
	k.type = TYPE_STAT
	k.mid  = 25
	k.pid  = os.getpid()
	k.loglevel = 5

	k.data = "ERROR!!! MERONG!!"
	print repr(k())

	k.data = "OH MY GOD! THEY KILLED KENNY!!"
	print repr(k())
