def offline_message_for_account(self, acct): reconnect = StateMixin.Reasons.WILL_RECONNECT if acct in self.reconnect_timers: if acct.offline_reason != reconnect: acct.offline_reason = reconnect rem_time = self.reconnect_timers[acct].remaining return reconnect % nicetimecount(rem_time) elif acct.offline_reason == reconnect: if isinstance(acct, UpdateMixin): return reconnect % nicetimecount(acct.timer.remaining) else: return StateMixin.Reasons.CONN_FAIL elif acct.offline_reason == StateMixin.Reasons.NONE: return '' return acct.offline_reason
class FileTransfer(Observable): DATA_POINTS = 500 TIME_THRESHOLD = 30 ATROPHY_TIME = 3 states = FileTransferStates state = notifyprop('state') _xfer_display_strings = { # transfer state # xfer, "direction" string states.TRANSFERRING: lambda x: _('{completed} of {size} ({speed}/sec) -- {time} remain'). format(completed=util.nicebytecount(x.completed), size=util.nicebytecount(x.size), speed=util.nicebytecount(x.bytes_per_sec), time=util.nicetimecount(x.ETA)), states.FINISHED: lambda x: (_('Received from {name}') if x.direction == 'incoming' else _('Sent to {name}')).format(name=x.buddy.name), states.CONNECTING: lambda x: _('Connecting to {name}...').format(name=x.buddy.name), states.WAITING_FOR_BUDDY: lambda x: _('Waiting for {name} to accept file').format(name=x.buddy. name), states.WAITING_FOR_YOU: lambda _x: '', states.CANCELLED_BY_BUDDY: lambda x: _('Canceled by {name}').format(name=x.buddy.name), states.WAITING_FOR_BUDDY: lambda x: _('Waiting for {name} to accept file').format(name=x.buddy. name), states.CONN_FAIL_XFER: lambda x: (_('Failed during transfer from {name}') if x.direction == 'incoming' else _('Failed during transfer to {name}')).format(name=x.buddy.name), states.CONN_FAIL: lambda x: _('Failed to connect to {name}').format(name=x.buddy.name), states.PROXY_XFER_FILESIZE_ERROR: lambda _x: _('File size too big for proxy transfer'), } def __init__(self): Observable.__init__(self) self.state = self.states.CONNECTING self.bytecounts = [] self._bytes_per_sec = 0 self.filepath = None self.completed = 0 self._starttime = None self._done = False self.xfer_display_strings = self._xfer_display_strings.copy() def get_right_links(self): return [('open', _('Open'), lambda *a: None, self.allow_open), ('cancel', _('Cancel'), self.cancel, self.allow_cancel), ('remove', _('Remove'), lambda *a: None, self.allow_remove)] def get_bottom_links(self): return [('save', _('Save'), self.save, self.allow_save), ('saveas', _('Save as...'), self.saveas, self.allow_save_as), ('reject', _('Reject'), self.decline, self.allow_reject)] @property def should_show_buddy_name(self): return self.state in (self.states.TRANSFERRING, self.states.WAITING_FOR_YOU) @property def details_string(self): return self.xfer_display_strings.get(self.state, lambda _x: self.state)(self) @property def elapsed(self): return default_timer() - self._starttime @property def average_speed(self): try: return self.completed / self.elapsed except ZeroDivisionError: return None @property def ETA(self): 'The estimated number of seconds until the trasnfer is complete.' try: return (self.size - self.completed) / self.bytes_per_sec except ZeroDivisionError: return 0 def _onrequest(self): # ask the user about the transfer self.protocol.hub.on_file_request(self.protocol, self) def _setcompleted(self, bytes): old = self.completed diff = bytes - old if diff <= 0: #log.debug('_setcompleted delta is <= 0 (%r - %r = %r)', bytes, old, diff) pass else: self._add_byte_data(default_timer(), bytes) self.setnotifyif('completed', bytes) @property def bytes_per_sec(self): now = default_timer() if self.state == self.states.TRANSFERRING: self._add_byte_data(now, self.completed) oldest = now newest = 0 lowest = self.completed for t, b in self.bytecounts: if (self.completed - b): oldest = t if oldest > t else oldest newest = t if newest < t else newest lowest = b if lowest > b else lowest time_diff = now - oldest byte_diff = self.completed - lowest time_since_recv = now - newest if (time_since_recv) > self.ATROPHY_TIME: # been a long time since we got bytes self._bytes_per_sec = 0 elif byte_diff and time_diff: self._bytes_per_sec = byte_diff / time_diff elif not byte_diff: self._bytes_per_sec = 0 elif not time_diff: # uhh...infinite? wha? pass return self._bytes_per_sec def _add_byte_data(self, time, bytecount): time = int(time) bytecounts = self.bytecounts actual = filter(lambda x: x[1], bytecounts) if not actual and bytecount: self._starttime = default_timer() if not bytecounts: bytecounts.append((time, bytecount)) oldtime = bytecounts[-1][0] if time > oldtime: bytecounts.append((time, bytecount)) elif time == oldtime: bytecounts[-1] = (time, bytecount) self.bytecounts = bytecounts[-self.TIME_THRESHOLD:] def get_default_dir(self): if pref('filetransfer.create_subfolders', False): service = self.protocol.service bname = self.buddy.name else: service = bname = '' return path(profile.localprefs['save_to_dir']) / service / bname def save(self, filepath=None): if filepath is None: try: orig = filepath = self.get_default_dir() / self.name except Exception: print_exc() # There was an exception getting the default file transfer save-to location. # Open a dialog and let the user choose, and then save this location as a # new location to save in. try: new_path = self.saveas(lookup_default=False) profile.localprefs['save_to_dir'] = os.path.dirname( new_path) except Exception: print_exc() return orig, ext = os.path.splitext(orig) i = 0 while os.path.exists(filepath): i += 1 filepath = orig + (' (%d)' % i) + ext import wx parent = os.path.split(filepath)[0] if not os.path.exists(parent): try: os.makedirs(parent) except EnvironmentError, e: strerror = e.strerror or _('Directory does not exist') wx.MessageBox("Error saving file to %s.\n%s" % (parent, strerror), style=wx.ICON_ERROR | wx.OK) return self.saveas() try: if pref('filetransfer.preallocate', False) and getattr( self, 'size', 0): self.allocate(filepath, self.size) f = open(filepath, 'wb') except EnvironmentError, e: wx.MessageBox("Error saving file to %s.\n%s" % (parent, e.strerror), style=wx.ICON_ERROR | wx.OK) return self.saveas()
def setup(self): FT.FileTransfer.__init__(self) self.name = _("Digsby Update") self.buddy = util.Storage(name = "Digsby Servers", alias = "Digsby Servers", icon = None) self.xfer_display_strings[self.states.CHECKING_FILES] = \ self.xfer_display_strings[self.states.TRANSFERRING] = \ lambda x, d=None: _('%s: %s of %s -- %s remain') % (x.state, x.completed, x.size, util.nicetimecount(x.ETA)) log.info("UpdateProgress setup")