comparison sat/plugins/plugin_exp_command_export.py @ 2624:56f94936df1e

code style reformatting using black
author Goffi <goffi@goffi.org>
date Wed, 27 Jun 2018 20:14:46 +0200
parents 26edcf3a30eb
children 003b8b4b56a7
comparison
equal deleted inserted replaced
2623:49533de4540b 2624:56f94936df1e
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core.log import getLogger 22 from sat.core.log import getLogger
23
23 log = getLogger(__name__) 24 log = getLogger(__name__)
24 from twisted.words.protocols.jabber import jid 25 from twisted.words.protocols.jabber import jid
25 from twisted.internet import reactor, protocol 26 from twisted.internet import reactor, protocol
26 27
27 from sat.tools import trigger 28 from sat.tools import trigger
33 C.PI_TYPE: "EXP", 34 C.PI_TYPE: "EXP",
34 C.PI_PROTOCOLS: [], 35 C.PI_PROTOCOLS: [],
35 C.PI_DEPENDENCIES: [], 36 C.PI_DEPENDENCIES: [],
36 C.PI_MAIN: "CommandExport", 37 C.PI_MAIN: "CommandExport",
37 C.PI_HANDLER: "no", 38 C.PI_HANDLER: "no",
38 C.PI_DESCRIPTION: _("""Implementation of command export""") 39 C.PI_DESCRIPTION: _("""Implementation of command export"""),
39 } 40 }
41
40 42
41 class ExportCommandProtocol(protocol.ProcessProtocol): 43 class ExportCommandProtocol(protocol.ProcessProtocol):
42 """ Try to register an account with prosody """ 44 """ Try to register an account with prosody """
43 45
44 def __init__(self, parent, client, target, options): 46 def __init__(self, parent, client, target, options):
47 self.options = options 49 self.options = options
48 self.client = client 50 self.client = client
49 51
50 def _clean(self, data): 52 def _clean(self, data):
51 if not data: 53 if not data:
52 log.error ("data should not be empty !") 54 log.error("data should not be empty !")
53 return u"" 55 return u""
54 decoded = data.decode('utf-8', 'ignore')[:-1 if data[-1] == '\n' else None] 56 decoded = data.decode("utf-8", "ignore")[: -1 if data[-1] == "\n" else None]
55 return clean_ustr(decoded) 57 return clean_ustr(decoded)
56 58
57 def connectionMade(self): 59 def connectionMade(self):
58 log.info("connectionMade :)") 60 log.info("connectionMade :)")
59 61
60 def outReceived(self, data): 62 def outReceived(self, data):
61 self.client.sendMessage(self.target, {'': self._clean(data)}, no_trigger=True) 63 self.client.sendMessage(self.target, {"": self._clean(data)}, no_trigger=True)
62 64
63 def errReceived(self, data): 65 def errReceived(self, data):
64 self.client.sendMessage(self.target, {'': self._clean(data)}, no_trigger=True) 66 self.client.sendMessage(self.target, {"": self._clean(data)}, no_trigger=True)
65 67
66 def processEnded(self, reason): 68 def processEnded(self, reason):
67 log.info (u"process finished: %d" % (reason.value.exitCode,)) 69 log.info(u"process finished: %d" % (reason.value.exitCode,))
68 self.parent.removeProcess(self.target, self) 70 self.parent.removeProcess(self.target, self)
69 71
70 def write(self, message): 72 def write(self, message):
71 self.transport.write(message.encode('utf-8')) 73 self.transport.write(message.encode("utf-8"))
72 74
73 def boolOption(self, key): 75 def boolOption(self, key):
74 """ Get boolean value from options 76 """ Get boolean value from options
75 @param key: name of the option 77 @param key: name of the option
76 @return: True if key exists and set to "true" (case insensitive), 78 @return: True if key exists and set to "true" (case insensitive),
79 return value.lower() == "true" 81 return value.lower() == "true"
80 82
81 83
82 class CommandExport(object): 84 class CommandExport(object):
83 """Command export plugin: export a command to an entity""" 85 """Command export plugin: export a command to an entity"""
86
84 # XXX: This plugin can be potentially dangerous if we don't trust entities linked 87 # XXX: This plugin can be potentially dangerous if we don't trust entities linked
85 # this is specially true if we have other triggers. 88 # this is specially true if we have other triggers.
86 # FIXME: spawned should be a client attribute, not a class one 89 # FIXME: spawned should be a client attribute, not a class one
87 90
88 def __init__(self, host): 91 def __init__(self, host):
89 log.info(_("Plugin command export initialization")) 92 log.info(_("Plugin command export initialization"))
90 self.host = host 93 self.host = host
91 self.spawned = {} # key = entity 94 self.spawned = {} # key = entity
92 host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=10000) 95 host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=10000)
93 host.bridge.addMethod("exportCommand", ".plugin", in_sign='sasasa{ss}s', out_sign='', method=self._exportCommand) 96 host.bridge.addMethod(
97 "exportCommand",
98 ".plugin",
99 in_sign="sasasa{ss}s",
100 out_sign="",
101 method=self._exportCommand,
102 )
94 103
95 def removeProcess(self, entity, process): 104 def removeProcess(self, entity, process):
96 """ Called when the process is finished 105 """ Called when the process is finished
97 @param entity: jid.JID attached to the process 106 @param entity: jid.JID attached to the process
98 @param process: process to remove""" 107 @param process: process to remove"""
99 try: 108 try:
100 processes_set = self.spawned[(entity, process.client.profile)] 109 processes_set = self.spawned[(entity, process.client.profile)]
101 processes_set.discard(process) 110 processes_set.discard(process)
102 if not processes_set: 111 if not processes_set:
103 del(self.spawned[(entity, process.client.profile)]) 112 del (self.spawned[(entity, process.client.profile)])
104 except ValueError: 113 except ValueError:
105 pass 114 pass
106 115
107 def MessageReceivedTrigger(self, client, message_elt, post_treat): 116 def MessageReceivedTrigger(self, client, message_elt, post_treat):
108 """ Check if source is linked and repeat message, else do nothing """ 117 """ Check if source is linked and repeat message, else do nothing """
109 from_jid = jid.JID(message_elt["from"]) 118 from_jid = jid.JID(message_elt["from"])
110 spawned_key = (from_jid.userhostJID(), client.profile) 119 spawned_key = (from_jid.userhostJID(), client.profile)
111 120
112 if spawned_key in self.spawned: 121 if spawned_key in self.spawned:
113 try: 122 try:
114 body = message_elt.elements(C.NS_CLIENT, 'body').next() 123 body = message_elt.elements(C.NS_CLIENT, "body").next()
115 except StopIteration: 124 except StopIteration:
116 # do not block message without body (chat state notification...) 125 # do not block message without body (chat state notification...)
117 return True 126 return True
118 127
119 mess_data = unicode(body) + '\n' 128 mess_data = unicode(body) + "\n"
120 processes_set = self.spawned[spawned_key] 129 processes_set = self.spawned[spawned_key]
121 _continue = False 130 _continue = False
122 exclusive = False 131 exclusive = False
123 for process in processes_set: 132 for process in processes_set:
124 process.write(mess_data) 133 process.write(mess_data)
150 _jid = _jid.userhostJID() 159 _jid = _jid.userhostJID()
151 except (RuntimeError, jid.InvalidFormat, AttributeError): 160 except (RuntimeError, jid.InvalidFormat, AttributeError):
152 log.info(u"invalid target ignored: %s" % (target,)) 161 log.info(u"invalid target ignored: %s" % (target,))
153 continue 162 continue
154 process_prot = ExportCommandProtocol(self, client, _jid, options) 163 process_prot = ExportCommandProtocol(self, client, _jid, options)
155 self.spawned.setdefault((_jid, client.profile),set()).add(process_prot) 164 self.spawned.setdefault((_jid, client.profile), set()).add(process_prot)
156 reactor.spawnProcess(process_prot, command, args, usePTY = process_prot.boolOption('pty')) 165 reactor.spawnProcess(
166 process_prot, command, args, usePTY=process_prot.boolOption("pty")
167 )