307 lines
12 KiB
Python
Executable File
307 lines
12 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: iso-8859-15 -*-
|
|
|
|
|
|
# Glasnost
|
|
# By: Odile Bénassy <obenassy@entrouvert.com>
|
|
# Romain Chantereau <rchantereau@entrouvert.com>
|
|
# Nicolas Clapiès <nclapies@easter-eggs.org>
|
|
# Pierre-Antoine Dejace <padejace@entrouvert.be>
|
|
# Thierry Dulieu <tdulieu@easter-eggs.com>
|
|
# Florent Monnier <monnier@codelutin.com>
|
|
# Cédric Musso <cmusso@easter-eggs.org>
|
|
# Frédéric Péters <fpeters@entrouvert.be>
|
|
# Benjamin Poussin <poussin@codelutin.com>
|
|
# Emmanuel Raviart <eraviart@entrouvert.com>
|
|
# Sébastien Régnier <regnier@codelutin.com>
|
|
# Emmanuel Saracco <esaracco@easter-eggs.com>
|
|
#
|
|
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
|
|
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
|
|
# Emmanuel Saracco & Théridion
|
|
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
|
|
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
|
|
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
|
|
# Régnier, Emmanuel Saracco, Théridion & Vecam
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
__doc__ = """Glasnost NCards Server"""
|
|
|
|
__version__ = '$Revision$'[11:-2]
|
|
|
|
|
|
import fcntl
|
|
import new
|
|
import sys
|
|
|
|
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
|
|
sys.path.insert(0, glasnostPythonDir)
|
|
|
|
import glasnost
|
|
|
|
from glasnost.common.NCardsCommon import *
|
|
import glasnost.common.faults as faults
|
|
import glasnost.common.context as context
|
|
import glasnost.common.tools_new as commonTools
|
|
import glasnost.common.xhtmlgenerator as X
|
|
|
|
from glasnost.server.ObjectsServer import register, ObjectServerMixin, \
|
|
AdminServerMixin, ObjectsServer, VirtualServer
|
|
from glasnost.proxy.DispatcherProxy import getApplicationToken, registerVirtualServer
|
|
|
|
from glasnost.server.tools import *
|
|
|
|
|
|
applicationName = 'NCardsServer'
|
|
applicationRole = 'ncards'
|
|
dispatcher = None
|
|
|
|
|
|
def registerNCardClass(ncard):
|
|
commonMixinClass = getCommonMixinClass(ncard)
|
|
|
|
objectClass = new.classobj(
|
|
commonMixinClass.objectClass.__name__,
|
|
(ObjectServerMixin, commonMixinClass.objectClass),
|
|
{})
|
|
setattr(sys.modules['__main__'], objectClass.__name__, objectClass)
|
|
register(objectClass)
|
|
|
|
objectAdminClass = new.classobj(
|
|
commonMixinClass.adminClass.__name__,
|
|
(AdminServerMixin, commonMixinClass.adminClass),
|
|
{})
|
|
setattr(sys.modules['__main__'],
|
|
objectAdminClass.__name__, objectAdminClass)
|
|
register(objectAdminClass)
|
|
|
|
|
|
class AdminNCards(AdminServerMixin, AdminNCardsCommon):
|
|
pass
|
|
register(AdminNCards)
|
|
|
|
|
|
class NCard(ObjectServerMixin, NCardCommon):
|
|
pass
|
|
register(NCard)
|
|
|
|
|
|
class NCardsServer(NCardsCommonMixin, ObjectsServer):
|
|
def addDispatcher(self, newDispatcherId):
|
|
ObjectsServer.addDispatcher(self, newDispatcherId)
|
|
virtualServer = self.getVirtualServer(
|
|
'/'.join((newDispatcherId, 'ncards')))
|
|
for object in virtualServer.objects.values():
|
|
vsId = commonTools.makeApplicationId(newDispatcherId, object.role)
|
|
self.registerSub(object, vsId)
|
|
|
|
def addObjectXmlRpc(self, objectImport):
|
|
objectId = ObjectsServer.addObjectXmlRpc(self, objectImport)
|
|
if commonTools.extractRole(objectId) == 'ncards':
|
|
virtualServerId = context.getVar('applicationId')
|
|
virtualServer = self.getVirtualServer(virtualServerId)
|
|
object = virtualServer.loadObjectCore(objectId)
|
|
newDispatcherId = commonTools.extractDispatcherId(virtualServerId)
|
|
vsId = commonTools.makeApplicationId(newDispatcherId, object.role)
|
|
self.registerSub(object, vsId)
|
|
return objectId
|
|
|
|
def modifyObjectXmlRpc(self, objectImport):
|
|
objectId = objectImport['id']
|
|
version = ObjectsServer.modifyObjectXmlRpc(self, objectImport)
|
|
if commonTools.extractRole(objectId) == 'ncards':
|
|
virtualServerId = context.getVar('applicationId')
|
|
virtualServer = self.getVirtualServer(virtualServerId)
|
|
object = virtualServer.loadObjectCore(objectId)
|
|
newDispatcherId = commonTools.extractDispatcherId(virtualServerId)
|
|
vsId = commonTools.makeApplicationId(newDispatcherId, object.role)
|
|
self.registerSub(object, vsId)
|
|
return version
|
|
|
|
def registerSub(self, object, vsId):
|
|
try:
|
|
registerVirtualServer(self.hostName, self.port, vsId)
|
|
except faults.RoleNotInProfiles:
|
|
return
|
|
registerNCardClass(object)
|
|
newVirtualServer = self.initVirtualServer(vsId)
|
|
self.virtualServers[vsId] = newVirtualServer
|
|
newVirtualServer = self.loadVirtualServer(newVirtualServer)
|
|
self.virtualServers[vsId] = newVirtualServer
|
|
context.push(applicationId = vsId)
|
|
context.getVar('applicationTokens')[vsId] = getApplicationToken()
|
|
context.pull()
|
|
|
|
def getApplicationNameFromVirtualServer(self, virtualServer):
|
|
dispatcherId = commonTools.extractDispatcherId(
|
|
virtualServer.virtualServerId)
|
|
role = commonTools.extractRole(virtualServer.virtualServerId)
|
|
virtualServer = self.virtualServers['/'.join((dispatcherId, 'ncards'))]
|
|
for o in virtualServer.objects.values():
|
|
if o.role == role:
|
|
applicationName = o.objectsName + 'Server'
|
|
return applicationName
|
|
raise 'aie'
|
|
|
|
|
|
def getObjectEmail(self, objectId):
|
|
clientToken = context.getVar('clientToken')
|
|
clientId = getApplicationId(clientToken)
|
|
clientRole = commonTools.extractRole(clientId)
|
|
if clientRole != 'identities':
|
|
raise faults.ApplicationAccessDenied(clientId)
|
|
|
|
virtualServerId = context.getVar('applicationId')
|
|
virtualServer = self.getVirtualServer(virtualServerId)
|
|
object = virtualServer.loadObjectCore(objectId)
|
|
emailAddress = object.getEmail()
|
|
if not emailAddress:
|
|
return '' # or raise something ?
|
|
|
|
return emailAddress
|
|
|
|
|
|
def loadVirtualServer(self, virtualServer):
|
|
# ObjectsServer.loadVirtualServer; modified to user ncard.objectName
|
|
# instead of self.applicationName
|
|
role = commonTools.extractRole(virtualServer.virtualServerId)
|
|
applicationName = self.applicationName
|
|
if role != 'ncards':
|
|
applicationName = self.getApplicationNameFromVirtualServer(
|
|
virtualServer)
|
|
|
|
context.push(
|
|
applicationId = virtualServer.virtualServerId,
|
|
dispatcherId = commonTools.extractDispatcherId(
|
|
virtualServer.virtualServerId),
|
|
emptyVirtualServer = virtualServer,
|
|
)
|
|
if self.useDataFile:
|
|
try:
|
|
pickleFilePath = os.path.join(
|
|
virtualServer.dataDirectoryPath,
|
|
applicationName + '.pickle')
|
|
xmlFilePath = os.path.join(
|
|
virtualServer.dataDirectoryPath,
|
|
applicationName + '.xml')
|
|
print 'pickleFilePath:', pickleFilePath
|
|
rcFile = None
|
|
if os.access(xmlFilePath, os.F_OK):
|
|
rcFile = open(xmlFilePath, 'rb')
|
|
import gnosis.xml.pickle as glasnostPickle
|
|
glasnostPickle.setParanoia(0)
|
|
elif os.access(pickleFilePath, os.F_OK):
|
|
import cPickle as glasnostPickle
|
|
rcFile = open(pickleFilePath, 'rb')
|
|
if rcFile is None:
|
|
self.fillEmptyVirtualServer(virtualServer)
|
|
else:
|
|
fcntl.lockf(rcFile, fcntl.LOCK_SH)
|
|
version = self.readFileVersion(rcFile)
|
|
print 'file:', rcFile
|
|
try:
|
|
data = glasnostPickle.load(rcFile)
|
|
except AttributeError:
|
|
self.fillEmptyVirtualServer(virtualServer)
|
|
data = virtualServer
|
|
fcntl.lockf(rcFile, fcntl.LOCK_UN)
|
|
isReadOnly = 0
|
|
if not os.access(rcFile.name, os.W_OK):
|
|
print '\t(read-only file)'
|
|
isReadOnly = 1
|
|
rcFile.close()
|
|
if isinstance(data, VirtualServer):
|
|
virtualServer = data
|
|
else:
|
|
virtualServer.initFromOldData(data)
|
|
virtualServer.isReadOnly = isReadOnly
|
|
self.upgradeVirtualServer(virtualServer, version)
|
|
finally:
|
|
context.pull()
|
|
return virtualServer
|
|
|
|
|
|
def registerToDispatcher(self):
|
|
ObjectsServer.registerToDispatcher(self)
|
|
for virtualServer in self.virtualServers.values():
|
|
newDispatcherId = commonTools.extractDispatcherId(
|
|
virtualServer.virtualServerId)
|
|
for object in virtualServer.objects.values():
|
|
vsId = commonTools.makeApplicationId(newDispatcherId, object.role)
|
|
self.registerSub(object, vsId)
|
|
|
|
|
|
def saveVirtualServer(self, virtualServer):
|
|
if not self.useDataFile:
|
|
return
|
|
if virtualServer.isReadOnly:
|
|
return
|
|
|
|
role = commonTools.extractRole(virtualServer.virtualServerId)
|
|
applicationName = self.applicationName
|
|
if role != 'ncards':
|
|
applicationName = self.getApplicationNameFromVirtualServer(
|
|
virtualServer)
|
|
|
|
import pickle as glasnostPickle
|
|
if not os.access(virtualServer.dataDirectoryPath, os.F_OK):
|
|
os.mkdir(virtualServer.dataDirectoryPath)
|
|
os.chmod(virtualServer.dataDirectoryPath, 0750)
|
|
rcFilePath = os.path.join(
|
|
virtualServer.dataDirectoryPath,
|
|
applicationName + '.pickle')
|
|
virtualServer.lock.acquire()
|
|
newRcFilePath = rcFilePath + '.new'
|
|
rcFile = open(newRcFilePath, 'wb')
|
|
os.chmod(newRcFilePath, 0640)
|
|
rcFile.write(glasnost.fileVersionNumber + '\n')
|
|
glasnostPickle.dump(virtualServer, rcFile, 1)
|
|
rcFile.close()
|
|
os.rename(newRcFilePath, rcFilePath)
|
|
virtualServer.lock.release()
|
|
xmlFilePath = os.path.join(
|
|
virtualServer.dataDirectoryPath,
|
|
applicationName + '.xml')
|
|
if os.access(xmlFilePath, os.F_OK):
|
|
os.remove(xmlFilePath)
|
|
|
|
def getObjectIdByRole(self, role):
|
|
virtualServerId = context.getVar('applicationId')
|
|
virtualServer = self.getVirtualServer(virtualServerId)
|
|
for object in virtualServer.objects.values():
|
|
if object.role == role:
|
|
return object.id
|
|
raise faults.MissingItem(role)
|
|
|
|
def registerPublicMethods(self):
|
|
ObjectsServer.registerPublicMethods(self)
|
|
self.registerPublicMethod('getObjectEmail')
|
|
self.registerPublicMethod('getObjectIdByRole')
|
|
|
|
def pushContext(self, virtualServerId, clientToken, userToken):
|
|
ObjectsServer.pushContext(self, virtualServerId, clientToken, userToken)
|
|
context.setVar('applicationId', virtualServerId)
|
|
|
|
ncardsServer = NCardsServer()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
ncardsServer.launch(applicationName, applicationRole)
|
|
|