codekingpro/portable-devtools
114k
1"""Utilities for Server Side connections.2 3 A collection of helpers for server side connection points.4"""5import pythoncom6import win32com.server.util7import winerror8from win32com import olectl9 10from .exception import Exception11 12# Methods implemented by the interfaces.13IConnectionPointContainer_methods = ["EnumConnectionPoints", "FindConnectionPoint"]14IConnectionPoint_methods = [15 "EnumConnections",16 "Unadvise",17 "Advise",18 "GetConnectionPointContainer",19 "GetConnectionInterface",20]21 22 23class ConnectableServer:24 _public_methods_ = IConnectionPointContainer_methods + IConnectionPoint_methods25 _com_interfaces_ = [26 pythoncom.IID_IConnectionPoint,27 pythoncom.IID_IConnectionPointContainer,28 ]29 30 # Clients must set _connect_interfaces_ = [...]31 def __init__(self):32 self.cookieNo = 033 self.connections = {}34 35 # IConnectionPoint interfaces36 def EnumConnections(self):37 raise Exception(winerror.E_NOTIMPL)38 39 def GetConnectionInterface(self):40 raise Exception(winerror.E_NOTIMPL)41 42 def GetConnectionPointContainer(self):43 return win32com.server.util.wrap(self)44 45 def Advise(self, pUnk):46 # Creates a connection to the client. Simply allocate a new cookie,47 # find the clients interface, and store it in a dictionary.48 try:49 interface = pUnk.QueryInterface(50 self._connect_interfaces_[0], pythoncom.IID_IDispatch51 )52 except pythoncom.com_error:53 raise Exception(scode=olectl.CONNECT_E_NOCONNECTION)54 self.cookieNo = self.cookieNo + 155 self.connections[self.cookieNo] = interface56 return self.cookieNo57 58 def Unadvise(self, cookie):59 # Destroy a connection - simply delete interface from the map.60 try:61 del self.connections[cookie]62 except KeyError:63 raise Exception(scode=winerror.E_UNEXPECTED)64 65 # IConnectionPointContainer interfaces66 def EnumConnectionPoints(self):67 raise Exception(winerror.E_NOTIMPL)68 69 def FindConnectionPoint(self, iid):70 # Find a connection we support. Only support the single event interface.71 if iid in self._connect_interfaces_:72 return win32com.server.util.wrap(self)73 74 def _BroadcastNotify(self, broadcaster, extraArgs):75 # Broadcasts a notification to all connections.76 # Ignores clients that fail.77 for interface in self.connections.values():78 try:79 broadcaster(*(interface,) + extraArgs)80 except pythoncom.com_error as details:81 self._OnNotifyFail(interface, details)82 83 def _OnNotifyFail(self, interface, details):84 print("Ignoring COM error to connection - %s" % (repr(details)))85 