#
# Extensible User Folder
# 
# BTree ZODB Property Source for exUserFolder
#
# (C) Copyright 2000,2001 The Internet (Aust) Pty Ltd
# ACN: 082 081 472  ABN: 83 082 081 472
# All Rights Reserved
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
#
# Author: Andrew Milton <akm@theinternet.com.au>
# $Id: zodbBTreePropSource.py,v 1.9 2003/07/05 21:38:36 akm Exp $
from Globals import HTMLFile, MessageDialog, INSTANCE_HOME,Acquisition
from Persistence import Persistent

from OFS.Folder import Folder

from Products.ZSQLMethods.SQL import SQL

from Products.exUserFolder.exUserFolder import exUserFolder
from Products.exUserFolder.Plugins import PluginRegister

import time
import zLOG, sys

from BTrees.OOBTree import OOBTree

manage_addPropSourceForm=HTMLFile('manage_addzodbBTreePropSourceForm', globals())

def manage_addzodbBTreePropSource(self, REQUEST):
	""" Add a Postgres Prop Source """

	o = zodbBTreePropSource()
	self._setObject('zodbBTreePropSource', o, None, None, 0)
	o = getattr(self, 'zodbBTreePropSource')

	# Allow Prop Source to setup default users...
	if hasattr(o, 'postInitialisation'):
		o.postInitialisation(REQUEST)
	self.currentPropSource=o

manage_addzodbBTreePropSourceForm=HTMLFile('manage_addzodbBTreePropSourceForm', globals())
manage_editzodbBTreePropSourceForm=HTMLFile('manage_editzodbBTreePropSourceForm', globals())


# Persistent container for properties
class UserProperty(Persistent):
	""" Attribute Bucket """
	
	def __init__(self):
		self.properties=OOBTree()

	def has_key(self, key):
		return self.properties.has_key(key)

	hasProperty=has_key
	
	def setProperty(self, key, value):
		self.properties[key]=value

	def getProperty(self, key, default=None):
		if self.properties.has_key(key):
			return self.properties[key]
		return default

	def delProperty(self, key):
		if self.properties.has_key(key):
			del self.properties[key]

	def keys(self):
		return tuple(self.properties.keys())
	
class zodbBTreePropSource(Folder):
	""" Store User Data in the BTree """

	meta_type='Property Source'
	title='ZODB BTree Properties'
	icon ='misc_/exUserFolder/exUserFolderPlugin.gif'	
	manage_editForm=manage_editzodbBTreePropSourceForm
	manage_tabs=Acquisition.Acquired

	def __init__(self):
		self.id='zodbBTreePropSource'
		self.userProperties=OOBTree()
		self.tempdict=OOBTree()
		
	def hasProperty(self, key):
		try:
			return self.userProperties[self.name].has_key(key)
		except:
			return default

	def setProperty(self, key, value):
		if not self.userProperties.has_key(self.name):
			self.userProperties[self.name]=UserProperty()
		self.userProperties[self.name].setProperty(key, value)
		
	def getProperty(self, key, default=None):
		try:
			return self.userProperties[self.name].getProperty(key, default)
		except:
			return default

	def delProperty(self, key):
		self.delUserProperty(key=key, username=self.name)

	def delUserProperty(self, key, username):
		try:
			self.userProperties[username].delProperty(key)
			self.tempdict[username].delProperty(key)
		except:
			pass

	def setTempProperty(self, key, value):
		self.setUserProperty(key=key, value=value, username=self.name, temp=1)

	def listProperties(self):
		try:
			return self.userProperties[self.name].keys()
		except:                        
			return []

	def getUserProperty(self, key, username, default = None):
		try:
			return self.userProperties[username].getProperty(key, default)
		except:
			return default

	def setUserProperty(self, key, username, value, temp=0):
		if not self.userProperties.has_key(username):
			self.userProperties[username]=UserProperty()

		self.userProperties[username].setProperty(key, value)
		
		if temp:
			if not self.tempdict.has_key(username):
				self.tempdict[username]=UserProperty()
			self.tempdict[username].setProperty(key, time.time())

	def flushTempProperties(self, age=0.0):
		if self.tempdict.has_key(self.name):
			now = time.time() - age
			for key in self.tempdict[self.name].keys():
				if self.tempdict[self.name][key] < now:
					delUserProperty(key, self.name)

	def listUserProperties(self, username):
		try:
			return self.userProperties[username].keys()
		except:
			return []
	
	def createUser(self, username, REQUEST):
		self.userProperties[username]=UserProperty()
		for k in REQUEST.keys():
			if k[:5]=='user_':
				key=k[5:]
				value=REQUEST[k]
				self.userProperties[username].setProperty(key, value)

	def deleteUsers(self, userids):
		for u in userids:
			if self.userProperties.has_key(u):
				del self.userProperties[u]

	def updateUser(self, username, REQUEST):
		for k in REQUEST.keys():
			if k[:5]=='user_':
				key=k[5:]
				value=REQUEST[k]
				self.userProperties[username].setProperty(key, value)
		
	# lists all users with props stored
	def listUsers(self):
		return self.userProperties.keys()
	

	def postInitialisation(self, REQUEST):
		pass

zodbBTreePropReg=PluginRegister('zodbBTreePropSource','ZODB BTree Property Source',
						   zodbBTreePropSource, manage_addzodbBTreePropSourceForm,
						   manage_addzodbBTreePropSource,
						   manage_editzodbBTreePropSourceForm)
exUserFolder.propSources['zodbBTreePropSource']=zodbBTreePropReg
