]> code.delx.au - pymsnt/blob - src/ft.py
Initial file transfer work
[pymsnt] / src / ft.py
1 # Copyright 2005 James Bunton <james@delx.cjb.net>
2 # Licensed for distribution under the GPL version 2, check COPYING for details
3
4 import disco
5 from debug import LogEvent, INFO, WARN, ERROR
6
7 if utils.checkTwisted():
8 from twisted.xish.domish import Element
9 else:
10 from tlib.domish import Element
11
12 import random
13 import sys
14
15 class FTReceive:
16 """ Manager for file transfers going from MSN to Jabber. """
17
18 """
19 Plan of action for this class:
20 * Determine the FT support of the Jabber client.
21 * If we support a common protocol with them, create an
22 FTReceive_Invite object of that type. Either OOB (JEP0066) or SI(JEP0095)
23 * Call doInvite() and wait on the Deferred to send an affirmative or
24 negative to the MSN contact.
25 * The InvitationReceive sends IQ packets to the Jabber user to see if they
26 accept. If they do it creates an appropriate FTReceive_Transport to send
27 the file. Returning a Deferred for success or failure.
28
29 """
30
31 def __init__(self, session, senderJID, legacyftp):
32 self.session = session
33 self.senderJID = senderJID
34 self.legacyftp = legacyftp
35 LogEvent(INFO)
36 self.checkSupport()
37
38 def checkSupport(self):
39 def discoDone(features):
40 c1 = features.count(disco.FT)
41 c2 = features.count(disco.S5)
42 c3 = features.count(disco.IBB)
43 c4 = features.count(disco.IQOOB)
44 #if c1 > 0 and c2 > 0:
45 # socksMode()
46 #elif c1 > 0 and c3 > 0:
47 # ibbMode()
48 if c4 > 0:
49 oobMode()
50 else:
51 messageOobMode()
52
53 def discoFail(ignored=None):
54 oobMode()
55
56 d = disco.DiscoRequest(self.session.pytrans, self.session.jabberID)
57 d.addCallback(discoDone)
58 d.addErrback(discoFail)
59
60 def socksMode(self):
61 LogEvent(ERROR)
62
63 def ibbMode(self):
64 LogEvent(ERROR)
65
66 def oobMode(self):
67 LogEvent(ERROR)
68
69 def messageOobMode(self):
70 global oobSite
71 self.legacyftp.accept()
72 filename = str(random.randint(0, sys.maxint))
73 oobSite.putFile(self, filename)
74 m = Element((None, "message"))
75 m.attributes["to"] = self.session.jabberID
76 m.attributes["from"] = self.senderJID
77 m.addElement("body").addContent(config.ftOOBRoot + "/" + filename)
78 x = m.addElement("x")
79 x.attributes["xmlns"] = disco.XOOB
80 x.addElement("url").addContent(config.ftOOBRoot + "/" + filename)
81 self.session.pytrans.send(m)
82
83 def error(self):
84 #FIXME
85
86
87
88
89 # Put the files up for OOB download
90
91 from twisted.web import server, resource, error
92 from twisted.internet import reactor
93
94 from debug import LogEvent, INFO, WARN, ERROR
95
96 class Connector:
97 def __init__(self, ftReceive, ftHttpPush):
98 self.ftReceive, self.ftHttpPush = ftReceive, ftHttpPush
99 self.ftReceive.legacyftp.writeTo(self)
100
101 def write(self, data):
102 self.ftHttpPush.write(data)
103
104 def close(self):
105 self.ftHttpPush.finish()
106
107 def error(self):
108 self.ftHttpPush.finish()
109 self.ftReceive.error()
110
111 class FileTransfer(resource.Resource):
112 def __init__(self):
113 self.isLeaf = True
114 self.files = {}
115
116 def putFile(self, file, filename):
117 self.files[filename] = file
118
119 def render_GET(self, request):
120 filename = "/" + request.path
121 if self.files.has_key(filename):
122 file = self.files[filename]
123 Connector(file, request)
124 del self.files[filename]
125 else:
126 page = error.NoResource(message="404 File Not Found")
127 return page.render(request)
128
129 oobSite = server.Site(FileTransfer())
130 reactor.listenTCP(8080, site)
131
132