<commit_before>
"""
        Ugly...

        work in progress, ment as proof of concept

        needs rewrite or cleanup
"""
__author__ = '<NAME> <<EMAIL>>'
__copyright__ = "Copyright (C) 2013 <NAME>"
__license__ = "BSD"


import time

import sys
# import os
# import traceback
import warnings
# import re
import base64
import socket
import select


import xml.etree.ElementTree as ET

from ISY.IsyEventData import EVENT_CTRL
import collections

try:
    import fcntl
except ImportError:
    fcntl = None

__all__ = ['ISYEvent']

class ISYEvent(object) :

    def __init__(self, addr=None, **kwargs):
        # print  "ISYEvent ", self.__class__.__name__

        self.debug = kwargs.get("debug", 0)
        self.connect_list = []
        self._shut_down = 0
        self.connected = False
        self.isy = kwargs.get("isy", None) 
	self.level = kwargs.get("level", "1") 

        self.process_func = kwargs.get("process_func", ISYEvent.print_event)
        self.process_func_arg = kwargs.get("process_func_arg", None)

        if self.process_func :
            assert isinstance(self.process_func, collections.Callable), \
                    "process_func Arg must me callable"

	addr = kwargs.get("addr", None)

        if addr :
	    userl = kwargs.get("userl", "admin")
	    userp = kwargs.get("userp", "admin")
	    authtuple = (  addr, userl, userp )
            self.connect_list.append(ISYEventConnection(self, authtuple) )


    def set_process_func(self, func, arg) :

        if func :
            self.process_func = func
            assert isinstance(self.process_func, collections.Callable), \
                    "process_func Arg must me callable"
        else:
            self.process_func = ISYEvent.print_event

        if arg :
            self.process_func_arg = arg



    def _finish(self)  :
        # print "Finishing... ", self.__class__.__name__
        for s in self.connect_list:
            s.disconnect()

        del self.connect_list[:]
        if self.isy :
            self.isy._isy_event = None
        # print "Finished... ", self.__class__.__name__

#    def __del__(self):
#       print "\n\n\n>>>>>>>>>__del__ ", \
#          self.__class__.__name__, "<<<<<<<<<<<<<\n\n\n"

    def _stop_event_loop(self) :
        # print self.__class__.__name__
        self._shut_down = 1

    # <?xml version="1.0" encoding="UTF-8"?><s:Envelope><s:Body>
    # <u:SetDebugLevel xmlns:u="urn:udi-com:service:X_Insteon_Lighting_Service:1">
    #<option>3</option></u:SetDebugLevel></s:Body></s:Envelope>
    def subscribe(self, **kwargs):
        """ subscribe to Isy device event stream

            this function adds an ISY device to the list of devices to
            receive events from

            named args:
		addr = IP address  or hostname of isydevice
		userl = isy admin login
		userp = isy admin password
		level = debug level
        """

	addr  = kwargs.get("addr", None)

        if self.debug & 0x01 :
            print("subscribe ", addr)

        if addr in self.connect_list :
	    # print "addr :", addr
	    print "connect_list :", self.connect_list
	    warnstr = str("Duplicate addr : {0}").format(addr)
            warnings.warn(warnstr, RuntimeWarning)
            return

	userl = kwargs.get("userl", "admin")
	userp = kwargs.get("userp", "admin")

	authtuple = (  addr, userl, userp )

        new_conn = ISYEventConnection(self, authtuple )

        # see if the other connections are connected
        # if so connect to avoid an error in select()
        if self.connected :
            new_conn.connect()

        self.connect_list.append(new_conn)

    def unsubscribe(self, addr):
        """ unsubscribe to Isy device event stream

            this function removes an ISY device to the list of devices to
            receive events from

            arg: IP address  or hostname of isydevice
        """
        remote_ip = socket.gethostbyname(addr)
        if not addr in self.connect_list :
            warnings.warn(
                "address {0}/{1} not subscribed".format(addr, remote_ip),
                RuntimeWarning)
            return
        isyconn = self.connect_list[self.connect_list.index(addr)]
        isyconn.disconnect()
        self.connect_list.remove(isyconn)
        del(isyconn)

    def _process_event(self, conn_obj) :
        """

            _process_event : takes XML from the events stream
                coverts to a dict and passed to process_func provided
        """
        #print "-"

        l = conn_obj.event_rf.readline()
        if len(l) == 0 :
            raise IOError("bad read form socket")
            # conn_obj._opensock(self.authtuple[0])
            # conn_obj._subscribe()
        # print "_process_event = ", l
        if (l[:5] != 'POST ') :
            print("Stream Sync Error")
            for x in range(10) :
                print(x, " ")
                l = conn_obj.event_rf.readline()
                if (l[:5] == 'POST ') :
                    break
            else :
                raise IOError("can not resync event stream")

        while 1 :
            l = conn_obj.event_rf.readline()
            if len(l) == 2 :
                break
            # print "HEADER : ", l
            if l[:15].upper() == "CONTENT-LENGTH:" :
                l.rstrip('\r\n')
                data_len = int(l.split(':')[1])

        # print "HEADER data_len ", data_len

        # data = conn_obj.event_rf.readread(data_len)
        data_remaining = data_len
        L = []
        while data_remaining :
            chunk = conn_obj.event_rf.read(data_remaining)
            if not chunk :
                break
            L.append(chunk)
            data_remaining -= len(chunk)
        data = ''.join(L)

        ddat = dict()

	# work around for encoding bug
	# in eventinfo field
	if data.find('< ') >= 0 :
	    data = data.replace('< ', '&lt; ')
	    data = data.replace('-->', '--&gt;')

	if data.find('<NULL>') :
	    data = data.replace('<NULL>', '&lt;NULL&gt;')

        # ev = ET.fromstring(data)
	try :
	    ev =  ET.fromstring(data)
	except ET.ParseError as e :
	    print "Etree ParseError "
	    print "data = ", data,
	    print "e.message = ", e.message
	    raise

        #print "_process_event ", data, "\n\n"


        ddat = self.et2d(ev)

        # print ddat
        #if ddat[control][0] == "_" :
        #       return
        # print ddat
        return(ddat, data)
        #return(ddat)<commit_msg>more workaround for bad XML<commit_after>
"""
        Ugly...

        work in progress, ment as proof of concept

        needs rewrite or cleanup
"""
__author__ = '<NAME> <<EMAIL>>'
__copyright__ = "Copyright (C) 2013 <NAME>"
__license__ = "BSD"


import time

import sys
# import os
# import traceback
import warnings
# import re
import base64
import socket
import select


import xml.etree.ElementTree as ET

from ISY.IsyEventData import EVENT_CTRL
import collections

try:
    import fcntl
except ImportError:
    fcntl = None

__all__ = ['ISYEvent']

class ISYEvent(object) :

    def __init__(self, addr=None, **kwargs):
        # print  "ISYEvent ", self.__class__.__name__

        self.debug = kwargs.get("debug", 0)
        self.connect_list = []
        self._shut_down = 0
        self.connected = False
        self.isy = kwargs.get("isy", None) 
	self.level = kwargs.get("level", "1") 

        self.process_func = kwargs.get("process_func", ISYEvent.print_event)
        self.process_func_arg = kwargs.get("process_func_arg", None)

        if self.process_func :
            assert isinstance(self.process_func, collections.Callable), \
                    "process_func Arg must me callable"

	addr = kwargs.get("addr", None)

        if addr :
	    userl = kwargs.get("userl", "admin")
	    userp = kwargs.get("userp", "admin")
	    authtuple = (  addr, userl, userp )
            self.connect_list.append(ISYEventConnection(self, authtuple) )


    def set_process_func(self, func, arg) :

        if func :
            self.process_func = func
            assert isinstance(self.process_func, collections.Callable), \
                    "process_func Arg must me callable"
        else:
            self.process_func = ISYEvent.print_event

        if arg :
            self.process_func_arg = arg



    def _finish(self)  :
        # print "Finishing... ", self.__class__.__name__
        for s in self.connect_list:
            s.disconnect()

        del self.connect_list[:]
        if self.isy :
            self.isy._isy_event = None
        # print "Finished... ", self.__class__.__name__

#    def __del__(self):
#       print "\n\n\n>>>>>>>>>__del__ ", \
#          self.__class__.__name__, "<<<<<<<<<<<<<\n\n\n"

    def _stop_event_loop(self) :
        # print self.__class__.__name__
        self._shut_down = 1

    # <?xml version="1.0" encoding="UTF-8"?><s:Envelope><s:Body>
    # <u:SetDebugLevel xmlns:u="urn:udi-com:service:X_Insteon_Lighting_Service:1">
    #<option>3</option></u:SetDebugLevel></s:Body></s:Envelope>
    def subscribe(self, **kwargs):
        """ subscribe to Isy device event stream

            this function adds an ISY device to the list of devices to
            receive events from

            named args:
		addr = IP address  or hostname of isydevice
		userl = isy admin login
		userp = isy admin password
		level = debug level
        """

	addr  = kwargs.get("addr", None)

        if self.debug & 0x01 :
            print("subscribe ", addr)

        if addr in self.connect_list :
	    # print "addr :", addr
	    print "connect_list :", self.connect_list
	    warnstr = str("Duplicate addr : {0}").format(addr)
            warnings.warn(warnstr, RuntimeWarning)
            return

	userl = kwargs.get("userl", "admin")
	userp = kwargs.get("userp", "admin")

	authtuple = (  addr, userl, userp )

        new_conn = ISYEventConnection(self, authtuple )

        # see if the other connections are connected
        # if so connect to avoid an error in select()
        if self.connected :
            new_conn.connect()

        self.connect_list.append(new_conn)

    def unsubscribe(self, addr):
        """ unsubscribe to Isy device event stream

            this function removes an ISY device to the list of devices to
            receive events from

            arg: IP address  or hostname of isydevice
        """
        remote_ip = socket.gethostbyname(addr)
        if not addr in self.connect_list :
            warnings.warn(
                "address {0}/{1} not subscribed".format(addr, remote_ip),
                RuntimeWarning)
            return
        isyconn = self.connect_list[self.connect_list.index(addr)]
        isyconn.disconnect()
        self.connect_list.remove(isyconn)
        del(isyconn)

    def _process_event(self, conn_obj) :
        """

            _process_event : takes XML from the events stream
                coverts to a dict and passed to process_func provided
        """
        #print "-"

        l = conn_obj.event_rf.readline()
        if len(l) == 0 :
            raise IOError("bad read form socket")
            # conn_obj._opensock(self.authtuple[0])
            # conn_obj._subscribe()
        # print "_process_event = ", l
        if (l[:5] != 'POST ') :
            print("Stream Sync Error")
            for x in range(10) :
                print(x, " ")
                l = conn_obj.event_rf.readline()
                if (l[:5] == 'POST ') :
                    break
            else :
                raise IOError("can not resync event stream")

        while 1 :
            l = conn_obj.event_rf.readline()
            if len(l) == 2 :
                break
            # print "HEADER : ", l
            if l[:15].upper() == "CONTENT-LENGTH:" :
                l.rstrip('\r\n')
                data_len = int(l.split(':')[1])

        # print "HEADER data_len ", data_len

        # data = conn_obj.event_rf.readread(data_len)
        data_remaining = data_len
        L = []
        while data_remaining :
            chunk = conn_obj.event_rf.read(data_remaining)
            if not chunk :
                break
            L.append(chunk)
            data_remaining -= len(chunk)
        data = ''.join(L)

        ddat = dict()

	# work around for encoding bugs
	# in eventinfo field
	if data.find('-->') >= 0 :
	    data = data.replace('-->', '--&gt;')

	if data.find('< ') >= 0 :
	    # print "< HACK"
	    data = data.replace('< ', '&lt; ')

	if data.find('<NULL>') :
	    data = data.replace('<NULL>', '&lt;NULL&gt;')

        # ev = ET.fromstring(data)
	try :
	    ev =  ET.fromstring(data)
	except ET.ParseError as e :
	    print "Etree ParseError "
	    print "data = ", data,
	    print "e.message = ", e.message
	    raise

        #print "_process_event ", data, "\n\n"


        ddat = self.et2d(ev)

        # print ddat
        #if ddat[control][0] == "_" :
        #       return
        # print ddat
        return(ddat, data)
        #return(ddat)
{'fraction_non_alphanumeric': 0.11857738003394538, 'fraction_numerical': 0.005477549760839377, 'mean_word_length': 1.9568886861313868, 'pattern_counts': {'":': 0, '<': 64, '<?xml version=': 2, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5851141', 'n_tokens_mistral': 4091, 'n_tokens_neox': 3909, 'n_words': 982}