Mercurial > libervia-backend
annotate frontends/src/jp/cmd_pipe.py @ 2528:65e278997715
component file sharing: comments metadata:
new <comments> element is added to file metadata, it contains the URL to the comments virtual node and the count of comments (this way client knows if it make sense to request comments or not).
Fixed triggers in plugin XEP-0264 (return value was missing).
New trigger in plugin XEP-0329 to allow component to add metadata (used here for comments url).
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 16 Mar 2018 18:43:11 +0100 |
parents | e2a7bb875957 |
children |
rev | line source |
---|---|
1960 | 1 #!/usr/bin/env python2 |
815 | 2 # -*- coding: utf-8 -*- |
3 | |
4 # jp: a SAT command line tool | |
2483 | 5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org) |
815 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
817 | 20 from sat_frontends.jp import base |
0 | 21 |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
22 from sat_frontends.jp.constants import Const as C |
817 | 23 import sys |
814 | 24 from sat.core.i18n import _ |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
25 from sat_frontends.tools import jid |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
26 import xml.etree.ElementTree as ET # FIXME: used temporarily to manage XMLUI |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
27 from functools import partial |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
28 import socket |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
29 import SocketServer |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
30 import errno |
0 | 31 |
817 | 32 __commands__ = ["Pipe"] |
0 | 33 |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
34 START_PORT = 9999 |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
35 |
817 | 36 class PipeOut(base.CommandBase): |
657 | 37 |
817 | 38 def __init__(self, host): |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
39 super(PipeOut, self).__init__(host, 'out', help=_('send a pipe a stream')) |
1864
96ba685162f6
jp: all commands now use the new start method and set need_loop in __init__ when needed
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
40 self.need_loop = True |
393 | 41 |
817 | 42 def add_parser_options(self): |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
43 self.parser.add_argument("jid", type=base.unicode_decoder, help=_("the destination jid")) |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
44 |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
45 def streamOutCb(self, port): |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
46 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
47 s.connect(('127.0.0.1', int(port))) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
48 while True: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
49 buf = sys.stdin.read(4096) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
50 if not buf: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
51 break |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
52 try: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
53 s.sendall(buf) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
54 except socket.error as e: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
55 if e.errno == errno.EPIPE: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
56 sys.stderr.write(str(e) + '\n') |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
57 self.host.quit(1) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
58 else: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
59 raise e |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
60 self.host.quit() |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
61 |
1864
96ba685162f6
jp: all commands now use the new start method and set need_loop in __init__ when needed
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
62 def start(self): |
817 | 63 """ Create named pipe, and send stdin to it """ |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
64 self.host.bridge.streamOut( |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
65 self.host.get_full_jid(self.args.jid), |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
66 self.profile, |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
67 callback=self.streamOutCb, |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
68 errback=partial(self.errback, |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
69 msg=_(u"can't start stream: {}"), |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
70 exit_code=C.EXIT_BRIDGE_ERRBACK)) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
71 |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
72 |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
73 class StreamServer(SocketServer.BaseRequestHandler): |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
74 |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
75 def handle(self): |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
76 while True: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
77 data = self.request.recv(4096) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
78 if not data: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
79 break |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
80 sys.stdout.write(data) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
81 try: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
82 sys.stdout.flush() |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
83 except IOError as e: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
84 sys.stderr.write(str(e) + '\n') |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
85 break |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
86 # calling shutdown will do a deadlock as we don't use separate thread |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
87 # this is a workaround (cf. https://stackoverflow.com/a/36017741) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
88 self.server._BaseServer__shutdown_request = True |
401
b2caa2615c4c
jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents:
393
diff
changeset
|
89 |
817 | 90 |
91 class PipeIn(base.CommandAnswering): | |
0 | 92 |
817 | 93 def __init__(self, host): |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
94 super(PipeIn, self).__init__(host, 'in', help=_('receive a pipe stream')) |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
95 self.action_callbacks = {"STREAM": self.onStreamAction} |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
96 |
817 | 97 def add_parser_options(self): |
98 self.parser.add_argument("jids", type=base.unicode_decoder, nargs="*", help=_('Jids accepted (none means "accept everything")')) | |
0 | 99 |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
100 def getXmluiId(self, action_data): |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
101 # FIXME: we temporarily use ElementTree, but a real XMLUI managing module |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
102 # should be available in the future |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
103 # TODO: XMLUI module |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
104 try: |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
105 xml_ui = action_data['xmlui'] |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
106 except KeyError: |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
107 self.disp(_(u"Action has no XMLUI"), 1) |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
108 else: |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
109 ui = ET.fromstring(xml_ui.encode('utf-8')) |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
110 xmlui_id = ui.get('submit') |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
111 if not xmlui_id: |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
112 self.disp(_(u"Invalid XMLUI received"), error=True) |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
113 return xmlui_id |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
114 |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
115 def onStreamAction(self, action_data, action_id, security_limit, profile): |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
116 xmlui_id = self.getXmluiId(action_data) |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
117 if xmlui_id is None: |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
118 return self.host.quitFromSignal(1) |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
119 try: |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
120 from_jid = jid.JID(action_data['meta_from_jid']) |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
121 except KeyError: |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
122 self.disp(_(u"Ignoring action without from_jid data"), 1) |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
123 return |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
124 |
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
125 if not self.bare_jids or from_jid.bare in self.bare_jids: |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
126 host, port = "localhost", START_PORT |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
127 while True: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
128 try: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
129 server = SocketServer.TCPServer((host, port), StreamServer) |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
130 except socket.error as e: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
131 if e.errno == errno.EADDRINUSE: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
132 port += 1 |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
133 else: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
134 raise e |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
135 else: |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
136 break |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
137 xmlui_data = {'answer': C.BOOL_TRUE, |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
138 'port': unicode(port)} |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
139 self.host.bridge.launchAction(xmlui_id, xmlui_data, profile_key=profile) |
2489
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
140 server.serve_forever() |
e2a7bb875957
plugin pipe/stream, file transfert: refactoring and improvments:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
141 self.host.quitFromSignal() |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
142 |
1864
96ba685162f6
jp: all commands now use the new start method and set need_loop in __init__ when needed
Goffi <goffi@goffi.org>
parents:
1766
diff
changeset
|
143 def start(self): |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
144 self.bare_jids = [jid.JID(jid_).bare for jid_ in self.args.jids] |
817 | 145 |
146 | |
147 class Pipe(base.CommandBase): | |
148 subcommands = (PipeOut, PipeIn) | |
149 | |
150 def __init__(self, host): | |
1670
3690b4d4157e
jp (pipe): pipe commands now use the new CommandAnswering API (with actionNew)
Goffi <goffi@goffi.org>
parents:
1396
diff
changeset
|
151 super(Pipe, self).__init__(host, 'pipe', use_profile=False, help=_('stream piping through XMPP')) |