comparison frontends/src/jp/cmd_pipe.py @ 1670:3690b4d4157e

jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
author Goffi <goffi@goffi.org>
date Wed, 25 Nov 2015 02:06:44 +0100
parents 069ad98b360d
children d17772b0fe22
comparison
equal deleted inserted replaced
1669:697effba0310 1670:3690b4d4157e
23 import sys 23 import sys
24 import os 24 import os
25 import os.path 25 import os.path
26 import shutil 26 import shutil
27 from sat.core.i18n import _ 27 from sat.core.i18n import _
28 from sat_frontends.tools import jid
29 import xml.etree.ElementTree as ET # FIXME: used temporarily to manage XMLUI
30
28 31
29 __commands__ = ["Pipe"] 32 __commands__ = ["Pipe"]
33
30 34
31 class PipeOut(base.CommandBase): 35 class PipeOut(base.CommandBase):
32 36
33 def __init__(self, host): 37 def __init__(self, host):
34 super(PipeOut, self).__init__(host, 'out', help=_('Pipe a stream out')) 38 super(PipeOut, self).__init__(host, 'out', help=_('send a pipe a stream'))
35 39
36 def add_parser_options(self): 40 def add_parser_options(self):
37 self.parser.add_argument("jid", type=base.unicode_decoder, help=_("The destination jid")) 41 self.parser.add_argument("jid", type=base.unicode_decoder, help=_("the destination jid"))
38 42
39 def pipe_out(self): 43 def pipe_out(self):
40 """ Create named pipe, and send stdin to it """ 44 """ Create named pipe, and send stdin to it """
41 tmp_dir = tempfile.mkdtemp() 45 tmp_dir = tempfile.mkdtemp()
42 fifopath = os.path.join(tmp_dir,"pipe_out") 46 fifopath = os.path.join(tmp_dir,"pipe_out")
43 os.mkfifo(fifopath) 47 os.mkfifo(fifopath)
44 self.host.bridge.pipeOut(self.host.get_full_jid(self.args.jid), fifopath, {}, self.profile) 48 self.host.bridge.pipeOut(self.host.get_full_jid(self.args.jid), fifopath, self.profile)
45 with open(fifopath, 'w') as f: 49 with open(fifopath, 'w') as f:
46 shutil.copyfileobj(sys.stdin, f) 50 shutil.copyfileobj(sys.stdin, f)
47 shutil.rmtree(tmp_dir) 51 shutil.rmtree(tmp_dir)
48 self.host.quit() 52 self.host.quit()
49 53
53 super(PipeOut, self).connected() 57 super(PipeOut, self).connected()
54 self.pipe_out() 58 self.pipe_out()
55 59
56 60
57 class PipeIn(base.CommandAnswering): 61 class PipeIn(base.CommandAnswering):
58 confirm_type = "PIPE_TRANSFER"
59 62
60 def __init__(self, host): 63 def __init__(self, host):
61 super(PipeIn, self).__init__(host, 'in', help=_('Wait for the reception of a pipe stream')) 64 super(PipeIn, self).__init__(host, 'in', help=_('receive a pipe stream'))
62 65 self.action_callbacks = {"PIPE": self.onPipeAction}
63 @property
64 def dest_jids(self):
65 return self.args.jids
66 66
67 def add_parser_options(self): 67 def add_parser_options(self):
68 self.parser.add_argument("jids", type=base.unicode_decoder, nargs="*", help=_('Jids accepted (none means "accept everything")')) 68 self.parser.add_argument("jids", type=base.unicode_decoder, nargs="*", help=_('Jids accepted (none means "accept everything")'))
69 69
70 def ask(self, data, confirm_id): 70 def getXmluiId(self, action_data):
71 answer_data = {} 71 # FIXME: we temporarily use ElementTree, but a real XMLUI managing module
72 tmp_dir = tempfile.mkdtemp() 72 # should be available in the futur
73 fifopath = os.path.join(tmp_dir,"pipe_in") 73 # TODO: XMLUI module
74 answer_data["dest_path"] = fifopath 74 try:
75 os.mkfifo(fifopath) 75 xml_ui = action_data['xmlui']
76 self.host.bridge.confirmationAnswer(confirm_id, True, answer_data, self.profile) 76 except KeyError:
77 with open(fifopath, 'r') as f: 77 self.disp(_(u"Action has no XMLUI"), 1)
78 shutil.copyfileobj(f, sys.stdout) 78 else:
79 shutil.rmtree(tmp_dir) 79 ui = ET.fromstring(xml_ui.encode('utf-8'))
80 self.host.quit() 80 xmlui_id = ui.get('submit')
81 if not xmlui_id:
82 self.disp(_(u"Invalid XMLUI received"), error=True)
83 return xmlui_id
84
85 def onPipeAction(self, action_data, action_id, security_limit, profile):
86 xmlui_id = self.getXmluiId(action_data)
87 if xmlui_id is None:
88 return self.host.quitFromSignal(1)
89 try:
90 from_jid = jid.JID(action_data['meta_from_jid'])
91 except KeyError:
92 self.disp(_(u"Ignoring action without from_jid data"), 1)
93 return
94
95 if not self.bare_jids or from_jid.bare in self.bare_jids:
96 tmp_dir = tempfile.mkdtemp()
97 fifopath = os.path.join(tmp_dir,"pipe_in")
98 os.mkfifo(fifopath)
99 xmlui_data = {'path': fifopath}
100 self.host.bridge.launchAction(xmlui_id, xmlui_data, profile_key=profile)
101
102 with open(fifopath, 'r') as f:
103 shutil.copyfileobj(f, sys.stdout)
104 shutil.rmtree(tmp_dir)
105 self.host.quit()
106
107 def run(self):
108 super(PipeIn, self).run()
109 self.bare_jids = [jid.JID(jid_).bare for jid_ in self.args.jids]
81 110
82 111
83 class Pipe(base.CommandBase): 112 class Pipe(base.CommandBase):
84 subcommands = (PipeOut, PipeIn) 113 subcommands = (PipeOut, PipeIn)
85 114
86 def __init__(self, host): 115 def __init__(self, host):
87 super(Pipe, self).__init__(host, 'pipe', use_profile=False, help=_('Stream piping through XMPP')) 116 super(Pipe, self).__init__(host, 'pipe', use_profile=False, help=_('stream piping through XMPP'))