|
From: <ni...@us...> - 2010-11-03 13:18:06
|
Revision: 65
http://openautomation.svn.sourceforge.net/openautomation/?rev=65&view=rev
Author: nilss1
Date: 2010-11-03 13:17:57 +0000 (Wed, 03 Nov 2010)
Log Message:
-----------
sorry, too many updates cleanup later, just want to keep a version in repo
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/connector.py
PyWireGate/trunk/datastore.py
PyWireGate/trunk/knx_connector/BusMonitor.py
PyWireGate/trunk/knx_connector/DPT_Types.py
PyWireGate/trunk/knx_connector/GroupSocket.py
PyWireGate/trunk/knx_connector/KNX_Connector.py
PyWireGate/trunk/owfs_connector/OWFS_Connector.py
PyWireGate/trunk/owfs_connector/connection.py
Added Paths:
-----------
PyWireGate/trunk/DSupdate.py
PyWireGate/trunk/simplejson/
PyWireGate/trunk/simplejson/.___init__.py
PyWireGate/trunk/simplejson/._decoder.py
PyWireGate/trunk/simplejson/._scanner.py
PyWireGate/trunk/simplejson/__init__.py
PyWireGate/trunk/simplejson/_speedups.c
PyWireGate/trunk/simplejson/decoder.py
PyWireGate/trunk/simplejson/encoder.py
PyWireGate/trunk/simplejson/ordered_dict.py
PyWireGate/trunk/simplejson/scanner.py
PyWireGate/trunk/simplejson/tests/
PyWireGate/trunk/simplejson/tests/.___init__.py
PyWireGate/trunk/simplejson/tests/._test_dump.py
PyWireGate/trunk/simplejson/tests/._test_errors.py
PyWireGate/trunk/simplejson/tests/._test_fail.py
PyWireGate/trunk/simplejson/tests/__init__.py
PyWireGate/trunk/simplejson/tests/test_check_circular.py
PyWireGate/trunk/simplejson/tests/test_decimal.py
PyWireGate/trunk/simplejson/tests/test_decode.py
PyWireGate/trunk/simplejson/tests/test_default.py
PyWireGate/trunk/simplejson/tests/test_dump.py
PyWireGate/trunk/simplejson/tests/test_encode_basestring_ascii.py
PyWireGate/trunk/simplejson/tests/test_encode_for_html.py
PyWireGate/trunk/simplejson/tests/test_errors.py
PyWireGate/trunk/simplejson/tests/test_fail.py
PyWireGate/trunk/simplejson/tests/test_float.py
PyWireGate/trunk/simplejson/tests/test_indent.py
PyWireGate/trunk/simplejson/tests/test_pass1.py
PyWireGate/trunk/simplejson/tests/test_pass2.py
PyWireGate/trunk/simplejson/tests/test_pass3.py
PyWireGate/trunk/simplejson/tests/test_recursion.py
PyWireGate/trunk/simplejson/tests/test_scanstring.py
PyWireGate/trunk/simplejson/tests/test_separators.py
PyWireGate/trunk/simplejson/tests/test_speedups.py
PyWireGate/trunk/simplejson/tests/test_unicode.py
PyWireGate/trunk/simplejson/tool.py
Added: PyWireGate/trunk/DSupdate.py
===================================================================
--- PyWireGate/trunk/DSupdate.py (rev 0)
+++ PyWireGate/trunk/DSupdate.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -0,0 +1,161 @@
+import getopt
+import ConfigParser
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+
+import datastore
+
+import sys
+
+class dbloader:
+ def __init__(self,config,fname):
+ self.config = config
+ self.dataobjects = {}
+ ## load datastore
+ self.load()
+ if config['type'].upper() == "KNX":
+ self.KNXloader(fname)
+ elif config['type'].upper() == "OWFS":
+ self.OWFSloader(fname)
+ self.save()
+
+ def readConfig(self,configfile):
+ cfile = open(configfile,"r")
+ ## fix for missingsectionheaders
+ while True:
+ pos = cfile.tell()
+ if cfile.readline().startswith("["):
+ break
+ cfile.seek(pos)
+ config = {}
+ configparse = ConfigParser.SafeConfigParser()
+ configparse.readfp(cfile)
+ for section in configparse.sections():
+ options = configparse.options(section)
+ config[section] = {}
+ for opt in options:
+ try:
+ config[section][opt] = configparse.getint(section,opt)
+ except ValueError:
+ try:
+ config[section][opt] = configparse.getfloat(section,opt)
+ except ValueError:
+ config[section][opt] = configparse.get(section,opt)
+
+ return config
+
+ def KNXloader(self,fname):
+ ga = self.readConfig(fname)
+ for key in ga.keys():
+ id = "%s:%s" % (self.config['namespace'],key)
+ self.dataobjects[id] = datastore.dataObject(False,id,unicode(ga[key]['name'],errors='ignore'))
+ self.dataobjects[id].config['dptid'] = ga[key]['dptsubid']
+
+ def OWFSloader(self,fname):
+ ow = self.readConfig(fname)
+ for key in ow.keys():
+ id = "%s:%s_temperature" % (self.config['namespace'],key)
+ print "add %s " % id
+ self.dataobjects[id] = datastore.dataObject(False,id,unicode(ow[key]['name'],errors='ignore'))
+ if 'resolution' in ow[key]:
+ self.dataobjects[id].config['resolution'] = ow[key]['resolution']
+ if 'eib_ga_temp' in ow[key]:
+ if len(ow[key]['eib_ga_temp']) >0:
+ knxid = "KNX:%s" % ow[key]['eib_ga_temp']
+ print "Try to attach to %s " % knxid
+ self.dataobjects[id].connected.append(knxid)
+ print "attaached"
+
+
+ def debug(self,msg=''):
+ print msg
+
+ def load(self):
+ ## TODO:
+ self.debug("load DATASTORE")
+ try:
+ db = open(self.config['datastore'],"rb")
+ #loaddict = pickle.Unpickler(db).load()
+ loaddict = json.load(db)
+ db.close()
+ for name, obj in loaddict.items():
+ self.dataobjects[name] = datastore.dataObject(False,obj['id'],obj['name'])
+ self.dataobjects[name].lastupdate = obj['lastupdate']
+ self.dataobjects[name].config = obj['config']
+ self.dataobjects[name].connected = obj['connected']
+ self.debug("%d entries loaded in DATASTORE" % len(self.dataobjects))
+ except:
+ ## no DB File
+ print "DB not found"
+ pass
+ ## Fixme: should belong to conncetor
+
+
+
+ def save(self):
+ ## TODO:
+ self.debug("save DATASTORE")
+ savedict = {}
+ ## FIXME: user create a __reduce__ method for the Datastoreitem object
+ for name,obj in self.dataobjects.items():
+ savedict[name] = {
+ 'name' : obj.name,
+ 'id' : obj.id,
+ 'value' : obj.value,
+ 'lastupdate' : obj.lastupdate,
+ 'config' : obj.config,
+ 'connected' : obj.connected
+ }
+ dbfile = open(self.config['datastore'],"wb")
+ #db = pickle.Pickler(dbfile,-1)
+ #db.dump(savedict)
+ json.dump(savedict,dbfile,sort_keys=True,indent=3)
+ dbfile.close()
+ for i in savedict.keys():
+ if len(savedict[i]['connected'])>0:
+ print savedict[i]
+
+
+if __name__ == "__main__":
+ import os
+ import sys
+ import getopt
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "f:d:n:t:", ["file=","datastore=","namespace=","type="])
+ except getopt.GetoptError:
+ print "Fehler"
+ sys.exit(2)
+ config = {
+ 'datastore' : 'datastore.db',
+ 'namespace' : 'KNX',
+ 'type' : False
+ }
+ fname = False
+ for opt, arg in opts:
+ if opt in ("-d","--datastore"):
+ config['datastore'] = arg
+
+ if opt in ("-n","--namespace"):
+ config['namespace'] = arg
+
+ if opt in ("-t","--type"):
+ config['type'] = arg
+
+ if opt in ("-f","--file"):
+ fname = arg
+
+ if not fname:
+ print "no configfilename"
+ sys.exit(1)
+ if not config['type']:
+ config['type'] = config['namespace']
+ dbloader(config,fname)
+
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/WireGate.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -58,6 +58,7 @@
self.config = self.readConfig("/etc/wiregate/pywiregate.conf")
defaultconfig = {
'pidfile' : "%s/wiregated.pid" % self.scriptpath,
+ 'datastore' : "%s/datastore.db" % self.scriptpath,
'logfile' : "%s/wiregated.log" % self.scriptpath,
'errorlog' : "%s/wiregated-error.log" % self.scriptpath,
'loglevel': 'info'
@@ -148,6 +149,7 @@
##Set Permissions
os.chown(self.config['WireGate']['pidfile'],runasuser[2],runasuser[3])
os.chown(self.config['WireGate']['logfile'],runasuser[2],runasuser[3])
+ os.chown(self.config['WireGate']['datastore'],runasuser[2],runasuser[3])
os.setregid(runasuser[3],runasuser[3])
os.setreuid(runasuser[2],runasuser[2])
@@ -251,8 +253,6 @@
## Logger for all instances that check/create logger based on Configfile
def log(self,msg,severity="info",instance="WireGate"):
- LEVELS = {'debug': logging.debug,'info': logging.info,'warning': logging.warning,'warn': logging.warning,'error': logging.error,'critical': logging.critical}
- level = LEVELS.get(severity, logging.info)
try:
logger = self.LOGGER[instance]
except KeyError:
@@ -262,8 +262,12 @@
logger.debug(msg)
elif severity=="info":
logger.info(msg)
+ elif severity=="notice":
+ logger.info(msg)
elif severity=="warning":
logger.warning(msg)
+ elif severity=="warn":
+ logger.warning(msg)
elif severity=="error":
logger.error(msg)
elif severity=="critical":
Modified: PyWireGate/trunk/connector.py
===================================================================
--- PyWireGate/trunk/connector.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/connector.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -47,6 +47,10 @@
pass
+ def setValue(self, dsobj):
+ self.log("unconfigured setValue in %r called for %s" % (self,dsobj.name) ,'warn','WireGate')
+ pass
+
import SocketServer
import socket
class ConnectorServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer,Connector):
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/datastore.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -1,7 +1,19 @@
import time
import threading
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+import sys
+import xml.dom.minidom
+
class datastore:
"""
Datastore Instance
@@ -16,23 +28,15 @@
##
####################################################
self.WG = WireGateInstance
+ self.log("DATASTORE starting up")
self.dataobjects = {}
-
+ self.locked = threading.RLock()
+ self.locked.acquire()
+ self.xmltag = lambda x,y,z='': len(z)>0 and "<%s %s>%s</%s>" % (x,z,y,x) or "<%s>%s</%s>" % (x,y,x)
## Load XML Database
self.load()
- ## Fixme: should belong to conncetor
- self.readgaconf()
-
- ## FIXME: that should belong to the Connector
- def readgaconf(self):
- ga = self.WG.readConfig("/etc/wiregate/eibga.conf")
- for key in ga.keys():
- obj = self.get("KNX:%s" % key)
- obj.dptid = ga[key]['dptsubid']
- obj.name = ga[key]['name']
-
def update(self,id,val):
## Update the communication Object with value
####################################################
@@ -44,14 +48,23 @@
## update or create a Datastoreobject
## schould be used by all connectors to set their Values
####################################################
+ ##
## get the Datastore object
obj = self.get(id)
self.debug("Updating %s (%s): %r" % (obj.name,id,val))
## Set the value of the object
obj.setValue(val)
-
+
##TODO: central subscriber function for other connectore or servers
+
+ for attached in obj.connected:
+ try:
+ self.dataobjects[attached].setValue(val,True)
+ except:
+ print "FAILED %s" % attached
+ __import__('traceback').print_exc(file=__import__('sys').stdout)
+ pass
## return the object for additional updates
@@ -66,6 +79,7 @@
## returns or create and returns the Dataobejct with ID id
##
####################################################
+ self.locked.acquire()
try:
## check for existence
type(self.dataobjects[id])
@@ -73,18 +87,88 @@
## create a new one if it don't exist
self.dataobjects[id] = dataObject(self.WG,id)
## return it
+ self.locked.release()
return self.dataobjects[id]
+ ## FIXME: that should belong to the Connector
+ def readgaconf(self):
+ print "SHOULD NOT BE CALLED"
+ ga = self.WG.readConfig("/etc/wiregate/eibga.conf")
+ for key in ga.keys():
+ obj = self.get("KNX:%s" % key)
+ obj.config['dptid'] = ga[key]['dptsubid']
+ obj.name = ga[key]['name']
+ obj._send = self.WG.connectors['KNX'].send
+
+
def load(self):
## TODO:
self.debug("load DATASTORE")
- pass
+ try:
+ db = open(self.WG.config['WireGate']['datastore'],"rb")
+ #loaddict = pickle.Unpickler(db).load()
+ loaddict = json.load(db)
+ db.close()
+ for name, obj in loaddict.items():
+ self.dataobjects[name] = dataObject(self.WG,obj['id'],obj['name'])
+ self.dataobjects[name].lastupdate = obj['lastupdate']
+ self.dataobjects[name].config = obj['config']
+ self.dataobjects[name].connected = obj['connected']
+ self.debug("%d entries loaded in DATASTORE" % len(self.dataobjects))
+ self.locked.release()
+ except IOError:
+ ## no DB File
+ pass
+ ## Fixme: should belong to conncetor
+ self.locked.release()
+ self.readgaconf()
+
+ except:
+ ## error
+ pass
+
def save(self):
## TODO:
self.debug("save DATASTORE")
- pass
+ self.locked.acquire()
+ savedict = {}
+ ## FIXME: user create a __reduce__ method for the Datastoreitem object
+ for name,obj in self.dataobjects.items():
+ savedict[name] = {
+ 'name' : obj.name,
+ 'id' : obj.id,
+ 'value' : obj.value,
+ 'lastupdate' : obj.lastupdate,
+ 'config' : obj.config,
+ 'connected' : obj.connected
+ }
+ dbfile = open(self.WG.config['WireGate']['datastore'],"wb")
+ #db = pickle.Pickler(dbfile,-1)
+ #db.dump(savedict)
+ json.dump(savedict,dbfile,sort_keys=True,indent=3)
+ dbfile.close()
+
+
+ def savetoXML(self):
+ objitemxml = ""
+ for name,obj in self.dataobjects.items():
+ configxml = ""
+ for cname,cval in obj.config.items():
+ configxml += self.xmltag(cname,cval)
+ objitemxml += self.xmltag(
+ "DSitem",
+ self.xmltag("id",name) +
+ self.xmltag("value",obj.getValue(),'type=%r' % type(obj.value).__name__) +
+ self.xmltag("config",configxml)
+ )
+ self.locked.release()
+ xmlout = xml.dom.minidom.parseString(self.xmltag("Datastore",objitemxml))
+ #xmlout = xmlout.toprettyxml(indent=" ")
+ xmlout = xmlout.toxml()
+ ## write binary to preserve UTF8
+ open(self.WG.config['WireGate']['datastore'],"wb").write(xmlout)
def debug(self,msg):
####################################################
@@ -109,6 +193,7 @@
## Threadlocking
self.write_mutex = threading.RLock()
self.read_mutex = threading.RLock()
+
## check for namespace
namespace = id.split(":",1)
if len(namespace)>1:
@@ -116,10 +201,14 @@
else:
## Fixme: maybe default Namespace
namespace = ""
+ self.namespace = namespace
+
+ if not name:
+ ## Initial Name
+ self.name = "%s:unbekannt-%s" % (namespace, time.strftime("%Y-%m-%d_%H:%M:%S"))
+ else:
+ self.name = name
- ## Initial Name
- self.name = "%s:unbekannt-%s" % (namespace, time.strftime("%Y-%m-%d_%H:%M:%S"))
-
## some defaults
self.value = ""
self.lastupdate = 0
@@ -132,9 +221,18 @@
self.config = {}
## connected Logics, communication objects ... goes here
- self.connected = {}
+ self.connected = []
- def setValue(self,val):
+ def _setValue(self,refered_self):
+ ## self override
+ print "Ovveride now"
+ if self.namespace:
+ self._setValue = self.WG.connectors[self.namespace].setValue
+ self.WG.connectors[self.namespace].setValue(refered_self)
+ ## override with connector send function
+ pass
+
+ def setValue(self,val,send=False):
try:
## get read lock
self.read_mutex.acquire()
@@ -143,6 +241,8 @@
## save the modified time
self.lastupdate = time.time()
self.value = val
+ if send:
+ self._setValue(self)
finally:
## release locks
self.write_mutex.release()
@@ -160,3 +260,39 @@
+#import json
+
+def JSON2DataStore(text):
+ obj = {}
+ return obj
+
+
+def DataStore2JSON(obj):
+ text = ""
+ return text
+
+class testtwo:
+ def __init__(self):
+ self.i=10
+ def _send(self,val):
+ """Hallo"""
+ print str(dir(self)) +str(val+self.i)
+
+class testthree:
+ def __init__(self):
+ self.u=1
+ def send(self,val):
+ """its me"""
+ print str(dir(self)) +str(self.u)
+
+
+
+if __name__ == "__main__":
+ two = testtwo()
+ two._send(20)
+ three = testthree()
+ two._send = three.send
+ two._send(20)
+ print two._send
+ print dir(two)
+
\ No newline at end of file
Modified: PyWireGate/trunk/knx_connector/BusMonitor.py
===================================================================
--- PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -20,11 +20,12 @@
import time
class busmonitor:
- def __init__(self, WireGateInstance):
+ def __init__(self, WireGateInstance,connectorInstance):
self.WG = WireGateInstance
+ self.KNX = connectorInstance
self.nicehex=lambda x: " ".join(map(lambda y:"%.2x" % y,x))
self.tobinstr=lambda n,b=8: "".join([str((n >> y) & 1) for y in range(b-1, -1, -1)])
- self.dpt = DPT_Types.dpt_type()
+ self.dpt = DPT_Types.dpt_type(WireGateInstance)
## FIXME: Not fully implemented
self.apcicodes = {
@@ -99,8 +100,9 @@
if msg['ctrl2']['DestAddrType'] == 0 and msg['apdu']['tpdu'] == "T_DATA_XXX_REQ":
msg['dstaddr'] = self._decodeGrpAddr(buf[3:5])
- id = "KNX:%s" % msg['dstaddr']
+ id = "%s:%s" % (self.KNX.instanceName, msg['dstaddr'])
+
## search Datastoreobject
dsobj = self.WG.DATASTORE.get(id)
## Decode the DPT Value
@@ -121,12 +123,8 @@
return msg
- def errormsg(self,msg=''):
- f=open("/tmp/WGerror","a+")
- __import__('traceback').print_exc(file=f)
- f.write(time.asctime())
- f.write("MSG:"+repr(msg))
- f.close()
+ def errormsg(self,msg=False):
+ self.WG.errorlog(msg)
def _decodeCtrlField1(self,raw):
Modified: PyWireGate/trunk/knx_connector/DPT_Types.py
===================================================================
--- PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -21,7 +21,7 @@
### sondern als LIST mit den dezimalen Werten ist das decode hier ein bischen angepasst
class dpt_type:
- def __init__(self,WireGateInstance=False):
+ def __init__(self,WireGateInstance):
self.WG = WireGateInstance
self.DECODER = {
1:self.decodeDPT1, # EIS 1/7 / 1 bit 0=Aus/1=Ein
@@ -50,7 +50,8 @@
if dptid > 0:
dpt = dptid
elif dsobj:
- dpt = dsobj.dptid
+ if "dptid" in dsobj.config:
+ dpt = dsobj.config['dptid']
else:
return False
if dpt == -1:
@@ -75,13 +76,18 @@
self.errormsg()
return raw
- def errormsg(self,msg=''):
- __import__('traceback').print_exc(file=__import__('sys').stdout)
+ def errormsg(self,msg=False):
+ self.WG.errormsg(msg)
def debug(self,msg):
- #print msg
- pass
+ self.log(msg,'debug')
+
+ def log(self,msg,severity='info',instance=False):
+ if not instance:
+ instance = "dpt-types"
+ self.WG.log(msg,severity,instance)
+
def toBigInt(self,raw):
c=0
res = 0
@@ -212,6 +218,7 @@
def decodeDPT16(self,raw):
res = ""
for char in raw:
+ ## stop on terminating \x00
if char == 0:
break
res += chr(char)
Modified: PyWireGate/trunk/knx_connector/GroupSocket.py
===================================================================
--- PyWireGate/trunk/knx_connector/GroupSocket.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/GroupSocket.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -20,11 +20,12 @@
import time
class groupsocket:
- def __init__(self, WireGateInstance):
+ def __init__(self, WireGateInstance, connectorInstance):
self.WG = WireGateInstance
+ self.KNX = connectorInstance
self.nicehex=lambda x: " ".join(map(lambda y:"%.2x" % y,x))
self.tobinstr=lambda n,b=8: "".join([str((n >> y) & 1) for y in range(b-1, -1, -1)])
- self.dpt = DPT_Types.dpt_type()
+ self.dpt = DPT_Types.dpt_type(WireGateInstance)
def decode(self,buf,src,dst):
## Accept List Hex or Binary Data
@@ -48,7 +49,7 @@
msg['srcaddr'] = self._decodePhysicalAddr(src)
try:
msg['dstaddr'] = self._decodeGrpAddr(dst)
- id = "KNX:%s" % msg['dstaddr']
+ id = "%s:%s" % (self.KNX.instanceName, msg['dstaddr'])
if (buf[0] & 0x3 or (buf[1] & 0xC0) == 0xC0):
##FIXME: unknown APDU
self.debug("unknown APDU from "+msg['srcaddr']+" to "+msg['dstaddr']+ " raw:"+buf)
@@ -78,13 +79,9 @@
return msg
- def errormsg(self,msg=''):
- f=open("/tmp/WGerror","a+")
- __import__('traceback').print_exc(file=f)
- f.write(time.asctime())
- f.write("MSG:"+repr(msg))
- f.close()
-
+ def errormsg(self,msg=False):
+ ## central error handling
+ self.WG.errorlog(msg)
def _decodePhysicalAddr(self,raw):
return "%d.%d.%d" % ((raw >> 12) & 0x0f, (raw >> 8) & 0x0f, (raw) & 0xff)
@@ -93,7 +90,7 @@
return "%d/%d/%d" % ((raw >> 11) & 0x1f, (raw >> 8) & 0x07, (raw) & 0xff)
def debug(self,msg):
- print "DEBUG: GROUPSOCKET: "+ repr(msg)
+ #print "DEBUG: GROUPSOCKET: "+ repr(msg)
pass
Modified: PyWireGate/trunk/knx_connector/KNX_Connector.py
===================================================================
--- PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -35,8 +35,8 @@
self.KNXBuffer = EIBConnection.EIBBuffer()
self.KNXSrc = EIBConnection.EIBAddr()
self.KNXDst = EIBConnection.EIBAddr()
- self.busmon = BusMonitor.busmonitor(WireGateInstance)
- self.groupsocket = GroupSocket.groupsocket(WireGateInstance)
+ self.busmon = BusMonitor.busmonitor(WireGateInstance,self)
+ self.groupsocket = GroupSocket.groupsocket(WireGateInstance,self)
## Deafaultconfig
defaultconfig = {
@@ -82,7 +82,7 @@
def _run(self):
while self.isrunning:
## Check if we are alive and responde until 10 secs
- self.WG.watchdog("knx_connector",10)
+ self.WG.watchdog(self.instanceName,10)
try:
vbusmonin, vbusmonout, vbusmonerr = select.select([self.KNX.EIB_Poll_FD()],[],[],1)
except:
@@ -114,3 +114,7 @@
if len(self.KNXBuffer.buffer) > 7 :
self.busmon.decode(self.KNXBuffer.buffer)
+
+
+ def send(self,dsobj):
+ print "SEND to %s" % dsobj.name
\ No newline at end of file
Modified: PyWireGate/trunk/owfs_connector/OWFS_Connector.py
===================================================================
--- PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -172,7 +172,7 @@
## loop through their interfaces
for get in self.busmaster[busname]['sensors'][sensor]['interfaces']:
resolution = ""
- id = "OW:"+sensor+"_"+get
+ id = "%s:%s_%s" % (self.instanceName,sensor,get)
## get the Datastore Object and look for config
obj = self.WG.DATASTORE.get(id)
@@ -205,4 +205,3 @@
threadname = "OWFS-Reader_%s" % busname
self.busmaster[busname]['readthread'] = threading.Thread(target=self._read,args=[busname],name=threadname)
self.busmaster[busname]['readthread'].start()
-
\ No newline at end of file
Modified: PyWireGate/trunk/owfs_connector/connection.py
===================================================================
--- PyWireGate/trunk/owfs_connector/connection.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/owfs_connector/connection.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -88,6 +88,7 @@
self._server = server
self._port = port
+ self.checknum = re.compile(r"(^\d+$)|(^\d+\x2e\d+$)", re.MULTILINE)
def __str__(self):
@@ -121,91 +122,120 @@
"""
"""
- #print 'Connection.read("%s", %i, "%s")' % (path)
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((self._server, self._port))
+ #print 'Connection.read("%s")' % (path)
+
+ rtn = None
+ ## we don't want errors
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((self._server, self._port))
+ except:
+ ##
+ return rtn
- smsg = self.pack(OWMsg.read, len(path) + 1, 8192)
- s.sendall(smsg)
- s.sendall(path + '\x00')
+ smsg = self.pack(OWMsg.read, len(path) + 1, 8192)
+ s.sendall(smsg)
+ s.sendall(path + '\x00')
- while 1:
- data = s.recv(24)
+ while 1:
+ try:
+ data = s.recv(24)
+ except:
+ ##
+ return rtn
- if len(data) is not 24:
- raise exShortRead
+ payload_len = -1
+ if len(data) is 24:
+ ret, payload_len, data_len = self.unpack(data)
- ret, payload_len, data_len = self.unpack(data)
+ if payload_len >= 0:
+ data = s.recv(payload_len)
+ return self.toNumber(data[:data_len])
+ break
+ else:
+ # ping response
+ return None
- if payload_len >= 0:
- data = s.recv(payload_len)
- rtn = self.toNumber(data[:data_len])
- break
- else:
- # ping response
- rtn = None
- break
+ finally:
+ s.close()
+
- s.close()
- return rtn
-
def write(self, path, value):
"""
"""
+ ret = None
+ try:
+ #print 'Connection.write("%s", "%s")' % (path, str(value))
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((self._server, self._port))
+ except:
+ return ret
- #print 'Connection.write("%s", "%s")' % (path, str(value))
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((self._server, self._port))
+ value = str(value)
+ smsg = self.pack(OWMsg.write, len(path) + 1 + len(value) + 1, len(value) + 1)
+ s.sendall(smsg)
+ s.sendall(path + '\x00' + value + '\x00')
- value = str(value)
- smsg = self.pack(OWMsg.write, len(path) + 1 + len(value) + 1, len(value) + 1)
- s.sendall(smsg)
- s.sendall(path + '\x00' + value + '\x00')
+ try:
+ data = s.recv(24)
+ except:
+ return ret
- data = s.recv(24)
+ if len(data) is 24:
+ ret, payload_len, data_len = self.unpack(data)
+ return ret
- if len(data) is not 24:
- raise exShortRead
+
+ finally:
+ s.close()
+
- ret, payload_len, data_len = self.unpack(data)
- s.close()
- return ret
-
-
def dir(self, path):
"""
"""
+
+ fields = []
+ try:
+ #print 'Connection.dir("%s")' % (path)
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((self._server, self._port))
+ except:
+ return fields
- #print 'Connection.dir("%s")' % (path)
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((self._server, self._port))
+ smsg = self.pack(OWMsg.dir, len(path) + 1, 0)
+ s.sendall(smsg)
+ s.sendall(path + '\x00')
- smsg = self.pack(OWMsg.dir, len(path) + 1, 0)
- s.sendall(smsg)
- s.sendall(path + '\x00')
+ while 1:
+ try:
+ data = s.recv(24)
+ except:
+ return fields
- fields = []
- while 1:
- data = s.recv(24)
+ if len(data) is not 24:
+ return fields
- if len(data) is not 24:
- raise exShortRead
+ ret, payload_len, data_len = self.unpack(data)
- ret, payload_len, data_len = self.unpack(data)
+ if payload_len > 0:
+ try:
+ data = s.recv(payload_len)
+ except:
+ return fields
+ fields.append(data[:data_len])
+ else:
+ # end of dir list or 'ping' response
+ return fields
- if payload_len > 0:
- data = s.recv(payload_len)
- fields.append(data[:data_len])
- else:
- # end of dir list or 'ping' response
- break
+ finally:
+ s.close()
- s.close()
- return fields
-
def pack(self, function, payload_len, data_len):
"""
"""
@@ -241,15 +271,15 @@
return ret_value, payload_len, data_len
- def toNumber(self, str):
+ def toNumber(self, owstr):
"""
"""
+ owstr = owstr.strip()
+ numresult = self.checknum.findall(owstr)
+ if numresult:
+ if numresult[0][0]:
+ return int(numresult[0][0])
+ elif numresult[0][1]:
+ return float(numresult[0][1])
- stripped = str.strip()
- if re.compile('^-?\d+$').match(stripped) :
- return int(stripped)
-
- if re.compile('^-?\d*\.\d*$').match(stripped) : # Could crash if it matched '.' - let it.
- return float(stripped)
-
- return str
+ return owstr
Added: PyWireGate/trunk/simplejson/.___init__.py
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/simplejson/.___init__.py
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/simplejson/._decoder.py
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/simplejson/._decoder.py
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/simplejson/._scanner.py
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/simplejson/._scanner.py
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/simplejson/__init__.py
===================================================================
--- PyWireGate/trunk/simplejson/__init__.py (rev 0)
+++ PyWireGate/trunk/simplejson/__init__.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -0,0 +1,437 @@
+r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of
+JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
+interchange format.
+
+:mod:`simplejson` exposes an API familiar to users of the standard library
+:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained
+version of the :mod:`json` library contained in Python 2.6, but maintains
+compatibility with Python 2.4 and Python 2.5 and (currently) has
+significant performance advantages, even without using the optional C
+extension for speedups.
+
+Encoding basic Python object hierarchies::
+
+ >>> import simplejson as json
+ >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
+ '["foo", {"bar": ["baz", null, 1.0, 2]}]'
+ >>> print json.dumps("\"foo\bar")
+ "\"foo\bar"
+ >>> print json.dumps(u'\u1234')
+ "\u1234"
+ >>> print json.dumps('\\')
+ "\\"
+ >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
+ {"a": 0, "b": 0, "c": 0}
+ >>> from StringIO import StringIO
+ >>> io = StringIO()
+ >>> json.dump(['streaming API'], io)
+ >>> io.getvalue()
+ '["streaming API"]'
+
+Compact encoding::
+
+ >>> import simplejson as json
+ >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
+ '[1,2,3,{"4":5,"6":7}]'
+
+Pretty printing::
+
+ >>> import simplejson as json
+ >>> s = json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=' ')
+ >>> print '\n'.join([l.rstrip() for l in s.splitlines()])
+ {
+ "4": 5,
+ "6": 7
+ }
+
+Decoding JSON::
+
+ >>> import simplejson as json
+ >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
+ >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
+ True
+ >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
+ True
+ >>> from StringIO import StringIO
+ >>> io = StringIO('["streaming API"]')
+ >>> json.load(io)[0] == 'streaming API'
+ True
+
+Specializing JSON object decoding::
+
+ >>> import simplejson as json
+ >>> def as_complex(dct):
+ ... if '__complex__' in dct:
+ ... return complex(dct['real'], dct['imag'])
+ ... return dct
+ ...
+ >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
+ ... object_hook=as_complex)
+ (1+2j)
+ >>> from decimal import Decimal
+ >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
+ True
+
+Specializing JSON object encoding::
+
+ >>> import simplejson as json
+ >>> def encode_complex(obj):
+ ... if isinstance(obj, complex):
+ ... return [obj.real, obj.imag]
+ ... raise TypeError(repr(o) + " is not JSON serializable")
+ ...
+ >>> json.dumps(2 + 1j, default=encode_complex)
+ '[2.0, 1.0]'
+ >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
+ '[2.0, 1.0]'
+ >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
+ '[2.0, 1.0]'
+
+
+Using simplejson.tool from the shell to validate and pretty-print::
+
+ $ echo '{"json":"obj"}' | python -m simplejson.tool
+ {
+ "json": "obj"
+ }
+ $ echo '{ 1.2:3.4}' | python -m simplejson.tool
+ Expecting property name: line 1 column 2 (char 2)
+"""
+__version__ = '2.1.2'
+__all__ = [
+ 'dump', 'dumps', 'load', 'loads',
+ 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
+ 'OrderedDict',
+]
+
+__author__ = 'Bob Ippolito <bo...@re...>'
+
+from decimal import Decimal
+
+from decoder import JSONDecoder, JSONDecodeError
+from encoder import JSONEncoder
+def _import_OrderedDict():
+ import collections
+ try:
+ return collections.OrderedDict
+ except AttributeError:
+ import ordered_dict
+ return ordered_dict.OrderedDict
+OrderedDict = _import_OrderedDict()
+
+def _import_c_make_encoder():
+ try:
+ from simplejson._speedups import make_encoder
+ return make_encoder
+ except ImportError:
+ return None
+
+_default_encoder = JSONEncoder(
+ skipkeys=False,
+ ensure_ascii=True,
+ check_circular=True,
+ allow_nan=True,
+ indent=None,
+ separators=None,
+ encoding='utf-8',
+ default=None,
+ use_decimal=False,
+)
+
+def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
+ allow_nan=True, cls=None, indent=None, separators=None,
+ encoding='utf-8', default=None, use_decimal=False, **kw):
+ """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
+ ``.write()``-supporting file-like object).
+
+ If ``skipkeys`` is true then ``dict`` keys that are not basic types
+ (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
+ will be skipped instead of raising a ``TypeError``.
+
+ If ``ensure_ascii`` is false, then the some chunks written to ``fp``
+ may be ``unicode`` instances, subject to normal Python ``str`` to
+ ``unicode`` coercion rules. Unless ``fp.write()`` explicitly
+ understands ``unicode`` (as in ``codecs.getwriter()``) this is likely
+ to cause an error.
+
+ If ``check_circular`` is false, then the circular reference check
+ for container types will be skipped and a circular reference will
+ result in an ``OverflowError`` (or worse).
+
+ If ``allow_nan`` is false, then it will be a ``ValueError`` to
+ serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
+ in strict compliance of the JSON specification, instead of using the
+ JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
+
+ If *indent* is a string, then JSON array elements and object members
+ will be pretty-printed with a newline followed by that string repeated
+ for each level of nesting. ``None`` (the default) selects the most compact
+ representation without any newlines. For backwards compatibility with
+ versions of simplejson earlier than 2.1.0, an integer is also accepted
+ and is converted to a string with that many spaces.
+
+ If ``separators`` is an ``(item_separator, dict_separator)`` tuple
+ then it will be used instead of the default ``(', ', ': ')`` separators.
+ ``(',', ':')`` is the most compact JSON representation.
+
+ ``encoding`` is the character encoding for str instances, default is UTF-8.
+
+ ``default(obj)`` is a function that should return a serializable version
+ of obj or raise TypeError. The default simply raises TypeError.
+
+ If *use_decimal* is true (default: ``False``) then decimal.Decimal
+ will be natively serialized to JSON with full precision.
+
+ To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
+ ``.default()`` method to serialize additional types), specify it with
+ the ``cls`` kwarg.
+
+ """
+ # cached encoder
+ if (not skipkeys and ensure_ascii and
+ check_circular and allow_nan and
+ cls is None and indent is None and separators is None and
+ encoding == 'utf-8' and default is None and not kw):
+ iterable = _default_encoder.iterencode(obj)
+ else:
+ if cls is None:
+ cls = JSONEncoder
+ iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
+ check_circular=check_circular, allow_nan=allow_nan, indent=indent,
+ separators=separators, encoding=encoding,
+ default=default, use_decimal=use_decimal, **kw).iterencode(obj)
+ # could accelerate with writelines in some versions of Python, at
+ # a debuggability cost
+ for chunk in iterable:
+ fp.write(chunk)
+
+
+def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
+ allow_nan=True, cls=None, indent=None, separators=None,
+ encoding='utf-8', default=None, use_decimal=False, **kw):
+ """Serialize ``obj`` to a JSON formatted ``str``.
+
+ If ``skipkeys`` is false then ``dict`` keys that are not basic types
+ (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``)
+ will be skipped instead of raising a ``TypeError``.
+
+ If ``ensure_ascii`` is false, then the return value will be a
+ ``unicode`` instance subject to normal Python ``str`` to ``unicode``
+ coercion rules instead of being escaped to an ASCII ``str``.
+
+ If ``check_circular`` is false, then the circular reference check
+ for container types will be skipped and a circular reference will
+ result in an ``OverflowError`` (or worse).
+
+ If ``allow_nan`` is false, then it will be a ``ValueError`` to
+ serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
+ strict compliance of the JSON specification, instead of using the
+ JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
+
+ If ``indent`` is a string, then JSON array elements and object members
+ will be pretty-printed with a newline followed by that string repeated
+ for each level of nesting. ``None`` (the default) selects the most compact
+ representation without any newlines. For backwards compatibility with
+ versions of simplejson earlier than 2.1.0, an integer is also accepted
+ and is converted to a string with that many spaces.
+
+ If ``separators`` is an ``(item_separator, dict_separator)`` tuple
+ then it will be used instead of the default ``(', ', ': ')`` separators.
+ ``(',', ':')`` is the most compact JSON representation.
+
+ ``encoding`` is the character encoding for str instances, default is UTF-8.
+
+ ``default(obj)`` is a function that should return a serializable version
+ of obj or raise TypeError. The default simply raises TypeError.
+
+ If *use_decimal* is true (default: ``False``) then decimal.Decimal
+ will be natively serialized to JSON with full precision.
+
+ To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
+ ``.default()`` method to serialize additional types), specify it with
+ the ``cls`` kwarg.
+
+ """
+ # cached encoder
+ if (not skipkeys and ensure_ascii and
+ check_circular and allow_nan and
+ cls is None and indent is None and separators is None and
+ encoding == 'utf-8' and default is None and not use_decimal
+ and not kw):
+ return _default_encoder.encode(obj)
+ if cls is None:
+ cls = JSONEncoder
+ return cls(
+ skipkeys=skipkeys, ensure_ascii=ensure_ascii,
+ check_circular=check_circular, allow_nan=allow_nan, indent=indent,
+ separators=separators, encoding=encoding, default=default,
+ use_decimal=use_decimal, **kw).encode(obj)
+
+
+_default_decoder = JSONDecoder(encoding=None, object_hook=None,
+ object_pairs_hook=None)
+
+
+def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, object_pairs_hook=None,
+ use_decimal=False, **kw):
+ """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
+ a JSON document) to a Python object.
+
+ *encoding* determines the encoding used to interpret any
+ :class:`str` objects decoded by this instance (``'utf-8'`` by
+ default). It has no effect when decoding :class:`unicode` objects.
+
+ Note that currently only encodings that are a superset of ASCII work,
+ strings of other encodings should be passed in as :class:`unicode`.
+
+ *object_hook*, if specified, will be called with the result of every
+ JSON object decoded and its return value will be used in place of the
+ given :class:`dict`. This can be used to provide custom
+ deserializations (e.g. to support JSON-RPC class hinting).
+
+ *object_pairs_hook* is an optional function that will be called with
+ the result of any object literal decode with an ordered list of pairs.
+ The return value of *object_pairs_hook* will be used instead of the
+ :class:`dict`. This feature can be used to implement custom decoders
+ that rely on the order that the key and value pairs are decoded (for
+ example, :func:`collections.OrderedDict` will remember the order of
+ insertion). If *object_hook* is also defined, the *object_pairs_hook*
+ takes priority.
+
+ *parse_float*, if specified, will be called with the string of every
+ JSON float to be decoded. By default, this is equivalent to
+ ``float(num_str)``. This can be used to use another datatype or parser
+ for JSON floats (e.g. :class:`decimal.Decimal`).
+
+ *parse_int*, if specified, will be called with the string of every
+ JSON int to be decoded. By default, this is equivalent to
+ ``int(num_str)``. This can be used to use another datatype or parser
+ for JSON integers (e.g. :class:`float`).
+
+ *parse_constant*, if specified, will be called with one of the
+ following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
+ can be used to raise an exception if invalid JSON numbers are
+ encountered.
+
+ If *use_decimal* is true (default: ``False``) then it implies
+ parse_float=decimal.Decimal for parity with ``dump``.
+
+ To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
+ kwarg.
+
+ """
+ return loads(fp.read(),
+ encoding=encoding, cls=cls, object_hook=object_hook,
+ parse_float=parse_float, parse_int=parse_int,
+ parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
+ use_decimal=use_decimal, **kw)
+
+
+def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, object_pairs_hook=None,
+ use_decimal=False, **kw):
+ """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
+ document) to a Python object.
+
+ *encoding* determines the encoding used to interpret any
+ :class:`str` objects decoded by this instance (``'utf-8'`` by
+ default). It has no effect when decoding :class:`unicode` objects.
+
+ Note that currently only encodings that are a superset of ASCII work,
+ strings of other encodings should be passed in as :class:`unicode`.
+
+ *object_hook*, if specified, will be called with the result of every
+ JSON object decoded and its return value will be used in place of the
+ given :class:`dict`. This can be used to provide custom
+ deserializations (e.g. to support JSON-RPC class hinting).
+
+ *object_pairs_hook* is an optional function that will be called with
+ the result of any object literal decode with an ordered list of pairs.
+ The return value of *object_pairs_hook* will be used instead of the
+ :class:`dict`. This feature can be used to implement custom decoders
+ that rely on the order that the key and value pairs are decoded (for
+ example, :func:`collections.OrderedDict` will remember the order of
+ insertion). If *object_hook* is also defined, the *object_pairs_hook*
+ takes priority.
+
+ *parse_float*, if specified, will be called with the string of every
+ JSON float to be decoded. By default, this is equivalent to
+ ``float(num_str)``. This can be used to use another datatype or parser
+ for JSON floats (e.g. :class:`decimal.Decimal`).
+
+ *parse_int*, if specified, will be called with the string of every
+ JSON int to be decoded. By default, this is equivalent to
+ ``int(num_str)``. This can be used to use another datatype or parser
+ for JSON integers (e.g. :class:`float`).
+
+ *parse_constant*, if specified, will be called with one of the
+ following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
+ can be used to raise an exception if invalid JSON numbers are
+ encountered.
+
+ If *use_decimal* is true (default: ``False``) then it implies
+ parse_float=decimal.Decimal for parity with ``dump``.
+
+ To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
+ kwarg.
+
+ """
+ if (cls is None and encoding is None and object_hook is None and
+ parse_int is None and parse_float is None and
+ parse_constant is None and object_pairs_hook is None
+ and not use_decimal and not kw):
+ return _default_decoder.decode(s)
+ if cls is None:
+ cls = JSONDecoder
+ if object_hook is not None:
+ kw['object_hook'] = object_hook
+ if object_pairs_hook is not None:
+ kw['object_pairs_hook'] = object_pairs_hook
+ if parse_float is not None:
+ kw['parse_float'] = parse_float
+ if parse_int is not None:
+ kw['parse_int'] = parse_int
+ if parse_constant is not None:
+ kw['parse_constant'] = parse_constant
+ if use_decimal:
+ if parse_float is not None:
+ raise TypeError("use_decimal=True implies parse_float=Decimal")
+ kw['parse_float'] = Decimal
+ return cls(encoding=encoding, **kw).decode(s)
+
+
+def _toggle_speedups(enabled):
+ import simplejson.decoder as dec
+ import simplejson.encoder as enc
+ import simplejson.scanner as scan
+ c_make_encoder = _import_c_make_encoder()
+ if enabled:
+ dec.scanstring = dec.c_scanstring or dec.py_scanstring
+ enc.c_make_encoder = c_make_encoder
+ enc.encode_basestring_ascii = (enc.c_encode_basestring_ascii or
+ enc.py_encode_basestring_ascii)
+ scan.make_scanner = scan.c_make_scanner or scan.py_make_scanner
+ else:
+ dec.scanstring = dec.py_scanstring
+ enc.c_make_encoder = None
+ enc.encode_basestring_ascii = enc.py_encode_basestring_ascii
+ scan.make_scanner = scan.py_make_scanner
+ dec.make_scanner = scan.make_scanner
+ global _default_decoder
+ _default_decoder = JSONDecoder(
+ encoding=None,
+ object_hook=None,
+ object_pairs_hook=None,
+ )
+ global _default_encoder
+ _default_encoder = JSONEncoder(
+ skipkeys=False,
+ ensure_ascii=True,
+ check_circular=True,
+ allow_nan=True,
+ indent=None,
+ separators=None,
+ encoding='utf-8',
+ default=None,
+ )
Added: PyWireGate/trunk/simplejson/_speedups.c
===================================================================
--- PyWireGate/trunk/simplejson/_speedups.c (rev 0)
+++ PyWireGate/trunk/simplejson/_speedups.c 2010-11-03 13:17:57 UTC (rev 65)
@@ -0,0 +1,2561 @@
+#include "Python.h"
+#include "structmember.h"
+#if PY_VERSION_HEX < 0x02070000 && !defined(PyOS_string_to_double)
+#define PyOS_string_to_double json_PyOS_string_to_double
+static double
+json_PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception);
+static double
+json_PyOS_string_to_double(const char *s, char **endptr, PyObject *overflow_exception) {
+ double x;
+ assert(endptr == NULL);
+ assert(overflow_exception == NULL);
+ PyFPE_START_PROTECT("json_PyOS_string_to_double", return -1.0;)
+ x = PyOS_ascii_atof(s);
+ PyFPE_END_PROTECT(x)
+ return x;
+}
+#endif
+#if PY_VERSION_HEX < 0x02060000 && !defined(Py_TYPE)
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#define PyInt_FromSsize_t PyInt_FromLong
+#define PyInt_AsSsize_t PyInt_AsLong
+#endif
+#ifndef Py_IS_FINITE
+#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
+#endif
+
+#ifdef __GNUC__
+#define UNUSED __attribute__((__unused__))
+#else
+#define UNUSED
+#endif
+
+#define DEFAULT_ENCODING "utf-8"
+
+#define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType)
+#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType)
+#define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType)
+#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType)
+#define Decimal_Check(op) (PyObject_TypeCheck(op, DecimalTypePtr))
+
+static PyTypeObject PyScannerType;
+static PyTypeObject PyEncoderType;
+static PyTypeObject *DecimalTypePtr;
+
+typedef struct _PyScannerObject {
+ PyObject_HEAD
+ PyObject *encoding;
+ PyObject *strict;
+ PyObject *object_hook;
+ PyObject *pairs_hook;
+ PyObject *parse_float;
+ PyObject *parse_int;
+ PyObject *parse_constant;
+ PyObject *memo;
+} PyScannerObject;
+
+static PyMemberDef scanner_members[] = {
+ {"encoding", T_OBJECT, offsetof(PyScannerObject, encoding), READONLY, "encoding"},
+ {"strict", T_OBJECT, offsetof(PyScannerObject, strict), READONLY, "strict"},
+ {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"},
+ {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, pairs_hook), READONLY, "object_pairs_hook"},
+ {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"},
+ {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"},
+ {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"},
+ {NULL}
+};
+
+typedef struct _PyEncoderObject {
+ PyObject_HEAD
+ PyObject *markers;
+ PyObject *defaultfn;
+ PyObject *encoder;
+ PyObject *indent;
+ PyObject *key_separator;
+ PyObject *item_separator;
+ PyObject *sort_keys;
+ PyObject *skipkeys;
+ PyObject *key_memo;
+ int fast_encode;
+ int allow_nan;
+ int use_decimal;
+} PyEncoderObject;
+
+static PyMemberDef encoder_members[] = {
+ {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"},
+ {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"},
+ {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"},
+ {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"},
+ {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"},
+ {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"},
+ {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"},
+ {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"},
+ {"key_memo", T_OBJECT, offsetof(PyEncoderObject, key_memo), READONLY, "key_memo"},
+ {NULL}
+};
+
+static Py_ssize_t
+ascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars);
+static PyObject *
+ascii_escape_unicode(PyObject *pystr);
+static PyObject *
+ascii_escape_str(PyObject *pystr);
+static PyObject *
+py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr);
+void init_speedups(void);
+static PyObject *
+scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
+static PyObject *
+scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
+static PyObject *
+_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
+static PyObject *
+scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+static int
+scanner_init(PyObject *self, PyObject *args, PyObject *kwds);
+static void
+scanner_dealloc(PyObject *self);
+static int
+scanner_clear(PyObject *self);
+static PyObject *
+encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+static int
+encoder_init(PyObject *self, PyObject *args, PyObject *kwds);
+static void
+encoder_dealloc(PyObject *self);
+static int
+encoder_clear(PyObject *self);
+static int
+encoder_listencode_list(PyEncoderObject *s, PyObject *rval, PyObject *seq, Py_ssize_t indent_level);
+static int
+encoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssize_t indent_level);
+static int
+encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ssize_t indent_level);
+static PyObject *
+_encoded_const(PyObject *obj);
+static void
+raise_errmsg(char *msg, PyObject *s, Py_ssize_t end);
+static PyObject *
+encoder_encode_string(PyEncoderObject *s, PyObject *obj);
+static int
+_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr);
+static PyObject *
+_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr);
+static PyObject *
+encoder_encode_float(PyEncoderObject *s, PyObject *obj);
+
+#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"')
+#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
+
+#define MIN_EXPANSION 6
+#ifdef Py_UNICODE_WIDE
+#define MAX_EXPANSION (2 * MIN_EXPANSION)
+#else
+#define MAX_EXPANSION MIN_EXPANSION
+#endif
+
+static int
+_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr)
+{
+ /* PyObject to Py_ssize_t converter */
+ *size_ptr = PyInt_AsSsize_t(o);
+ if (*size_ptr == -1 && PyErr_Occurred())
+ return 0;
+ return 1;
+}
+
+static PyObject *
+_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr)
+{
+ /* Py_ssize_t to PyObject converter */
+ return PyInt_FromSsize_t(*size_ptr);
+}
+
+static Py_ssize_t
+ascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars)
+{
+ /* Escape unicode code point c to ASCII escape sequences
+ in char *output. output must have at least 12 bytes unused to
+ accommodate an escaped surrogate pair "\uXXXX\uXXXX" */
+ output[chars++] = '\\';
+ switch (c) {
+ case '\\': output[chars++] = (char)c; break;
+ case '"': output[chars++] = (char)c; break;
+ case '\b': output[chars++] = 'b'; break;
+ case '\f': output[chars++] = 'f'; break;
+ case '\n': output[chars++] = 'n'; break;
+ case '\r': output[chars++] = 'r'; break;
+ case '\t': output[chars++] = 't'; break;
+ default:
+#ifdef Py_UNICODE_WIDE
+ if (c >= 0x10000) {
+ /* UTF-16 surrogate pair */
+ Py_UNICODE v = c - 0x10000;
+ c = 0xd800 | ((v >> 10) & 0x3ff);
+ output[chars++] = 'u';
+ output[...
[truncated message content] |