1
# -*- coding: utf-8 -*-
3
# This file is part of emesene.
5
# Emesene is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# emesene is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with emesene; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
import emesenelib.common
28
''' this class represents one filetransfer'''
30
def __init__(self, controller, p2p, conversation, session, context, sender):
32
The sender parameter accepts the special value "Me", which is not
33
a valid mail, and is used for sent files'''
36
#self.state should always be one of those states
42
self.controller = controller
44
self.conversation = conversation
45
self.session = int(session)
46
self.context = context
49
self.receivedBytes = 0
50
self.state = self.WAITING
52
self.timeAccepted = None
54
if context.preview != '':
55
loader = gtk.gdk.PixbufLoader()
56
loader.write(context.preview)
59
self.previewImage = loader.get_pixbuf()
62
self.previewImage = None
67
self.conversation.appendOutputText(None, \
68
_('Sending %s') % self.context.filename, 'information')
70
args = {'mail': self.p2p.mail, 'file': self.context.filename}
71
self.conversation.appendOutputText(None, \
72
_('%(mail)s is sending you %(file)s') % args, \
76
sap = self.signals.append
77
sap(self.p2p.connect('transfer-progress', self.onFtProgress))
78
sap(self.p2p.connect('transfer-failed', self.onFtFailed))
79
sap(self.p2p.connect('file-transfer-complete', self.onFtReceived))
81
sap(self.p2p.connect('file-transfer-accepted', self.onFtAccepted))
84
for identifier in self.signals:
85
self.p2p.disconnect(identifier)
87
def getPreviewImage(self):
88
return self.previewImage
91
'''returns a tuple with received and total bytes'''
92
return int(self.receivedBytes), int(self.context.file_size)
95
'''accept this transfer'''
97
self.conversation.appendOutputText(None, \
98
_('You have accepted %s') % self.context.filename, \
101
self.p2p.emit('file-transfer-accepted', self.session, self.context,
103
self.timeAccepted = time.time()
105
self.state = self.TRANSFERING
106
self.ui.stateChanged()
109
'''cancel this transfer'''
111
self.conversation.appendOutputText(None,
112
_('You have canceled the transfer of %s') % self.context.filename,
115
self.p2p.emit('file-transfer-canceled', self.session, self.context,
118
self.state = self.FAILED
119
self.ui.stateChanged()
122
def getElapsedTime(self):
123
'''return the time elapsed since this transfer was accepted'''
124
if not self.timeAccepted:
127
return int(time.time()) - int(self.timeAccepted)
129
def getAverageSpeed(self):
130
'''get average file transfer speed (bytes per second)'''
131
time = self.getElapsedTime()
132
if time == 0: # prevent division by zero
135
return self.receivedBytes / time
138
'''remove this transfer'''
139
self.conversation.transfers.remove(self)
142
def onFtAccepted(self, p2p, session, context, sender):
143
if session != self.session: return
145
self.conversation.appendOutputText(None, \
146
_('Starting transfer of %s') % self.context.filename, \
149
self.timeAccepted = time.time()
151
self.state = self.TRANSFERING
152
self.ui.stateChanged()
154
def onFtProgress(self, switchboard, session, bytes):
155
if session != self.session: return
157
self.receivedBytes = int(bytes)
158
self.ui.updateProgress()
160
def onFtFailed(self, switchboard, session, reason):
161
if session != self.session: return
163
output = _('Transfer of %s failed.') % self.context.filename + ' '
165
if reason == 'corrupt':
166
output += _('Some parts of the file are missing')
167
elif reason == 'cancelled':
168
output += _('Interrupted by user')
169
elif reason == 'error':
170
output += _('Transfer error')
171
self.conversation.appendOutputText(None, output, 'error')
173
self.state = self.FAILED
174
self.ui.stateChanged()
176
def onFtReceived(self, p2p, session, context, src, sender):
177
'''called when filetransfer is finished'''
178
if session != self.session: return
181
self.conversation.appendOutputText(None, \
182
_('%s sent successfully') % context.filename, 'information')
184
self.conversation.appendOutputText(None, \
185
_('%s received successfully.') % context.filename, \
187
self.conversation.doMessageWaiting(sender)
189
self.receivedBytes = context.file_size
190
self.state = self.RECEIVED
191
self.ui.stateChanged()
197
config = self.controller.config
198
receivedFilesDir = os.path.expanduser(config.user['receivedFilesDir'])
200
# if directory is invalid, save to home directory
201
if not os.path.exists(receivedFilesDir):
202
print receivedFilesDir + ' does not exist. ' \
203
'Saving files to home directory.'
204
receivedFilesDir = os.path.expanduser('~/')
206
name = os.path.join(receivedFilesDir, self.getFilename())
211
while os.path.exists(name + numstr):
213
numstr = '.' + str(num)
215
self.localPath = name + numstr
217
# we don't copy because the permissions may be too restrictive
218
# and not match the user preferred umask blah blah
219
dest = open(self.localPath, 'wb')
221
buffer = src.read(32 * 1024)
224
buffer = src.read(32 * 1024)
229
'''open received file'''
230
if self.localPath != None:
232
desktop.open(self.localPath)
236
def getFilename(self):
237
return self.context.filename
239
def setBytesReceived(self, bytes):
240
self.receivedBytes = bytes
242
def getFraction(self):
243
'''return the progress of this transfer as a float from 0 to 1'''
244
return float(self.receivedBytes) / float(self.context.file_size)