def calc_torrent_title(self): if self.metainfo is not None: # if we have metainfo, then we should use that return util.get_name_from_torrent_metadata( self.metainfo) elif is_magnet_uri(self.url): # as a fallback, we can try the title from the magnet URI return title_from_magnet(self.url) else: return None
def update_item_list(self, finished, file_migrated): if finished: for item in self.item_list: item.on_download_finished() elif file_migrated: self._file_migrated(old_filename) else: # update the torrent title; important for magnet URLs since we # don't have a real one when the download starts. The # old_filename check is to prevent things with existing titles # from being renamed (#18656). if self.metainfo is not None: torrent_title = util.get_name_from_torrent_metadata( self.metainfo) else: torrent_title = None size = self.total_size for item in self.item_list: if size != item.size or torrent_title != item.torrent_title: item.torrent_title = torrent_title item.size = size item.signal_change()
def update_status(cls, data, cmd_done=False): for field in data: if field not in ['filename', 'short_filename', 'metainfo']: data[field] = unicodify(data[field]) self = get_downloader_by_dlid(dlid=data['dlid']) # FIXME: how do we get all of the possible bit torrent # activity strings into gettext? --NN if data.has_key('activity') and data['activity']: data['activity'] = _(data['activity']) if self is not None: now = time.time() last_update = self.last_update state = self.get_state() new_state = data.get('state', u'downloading') # If this item was marked as pending update, then any update # which comes in now which does not have cmd_done set is void. if not cmd_done and self.status_updates_frozen: logging.debug( 'self = %s, ' 'saved state = %s ' 'downloader state = %s. ' 'Discard.', self, state, new_state) # treat as stale return False # If the state is one which we set and was meant to be passed # through to the downloader (valid_states), and the downloader # replied with something that was a response to a previous # download command, and state was also a part of valid_states, # but the saved state and the new state do not match # then it means the message is stale. # # Have a think about why this is true: when you set a state, # which is authoritative, to the downloader you expect it # to reply with that same state. If they do not match then it # means the message is stale. # # The exception to this rule is if the downloader replies with # an error state, or if downloading has transitioned to finished # state. # # This also does not apply to any state which we set on the # downloader via a restore command. A restore command before # a pause/resume/cancel will work as intended, and no special # trickery is required. A restore command which happens after # a pause/resume/cancel is void, so no work is required. # # I hope this makes sense and is clear! valid_states = (u'downloading', u'paused', u'stopped', u'uploading-paused', u'finished') if (cmd_done and state in valid_states and new_state in valid_states and state != new_state): if not (state == u'downloading' and new_state == u'finished'): logging.debug( 'self = %s STALE. ' 'Saved state %s, got state %s. Discarding.', self, state, new_state) return False # We are updating! Reset the status_updates_frozen flag. self.status_updates_frozen = False # We have something to update: update the last updated timestamp. self.last_update = now was_finished = self.is_finished() old_filename = self.get_filename() self.before_changing_rates() self.update_status_attributes(data) self.after_changing_rates() # Store the time the download finished finished = self.is_finished() and not was_finished name_changed = self.get_filename() != old_filename file_migrated = (self.is_finished() and name_changed) if ((self.get_state() == u'uploading' and not self.manualUpload and (app.config.get(prefs.LIMIT_UPLOAD_RATIO) and self.get_upload_ratio() > app.config.get( prefs.UPLOAD_RATIO)))): self.stop_upload() self.signal_change() if finished: for item in self.item_list: item.on_download_finished() elif file_migrated: self._file_migrated(old_filename) elif name_changed and old_filename and self.metainfo is not None: # update the torren title; happens with magnet URLs since we # don't have a real one when the download starts. The # old_filename check is to prevent things with existing titles # from being renamed (#18656). new_title = util.get_name_from_torrent_metadata(self.metainfo) for item in self.item_list: if item.torrent_title is None: item.torrent_title = new_title item.signal_change() return True
def update_status(cls, data, cmd_done=False): for field in data: if field not in ['filename', 'short_filename', 'metainfo']: data[field] = unicodify(data[field]) self = get_downloader_by_dlid(dlid=data['dlid']) # FIXME: how do we get all of the possible bit torrent # activity strings into gettext? --NN if data.has_key('activity') and data['activity']: data['activity'] = _(data['activity']) if self is not None: now = time.time() last_update = self.last_update state = self.get_state() new_state = data.get('state', u'downloading') # If this item was marked as pending update, then any update # which comes in now which does not have cmd_done set is void. if not cmd_done and self.status_updates_frozen: logging.debug('self = %s, ' 'saved state = %s ' 'downloader state = %s. ' 'Discard.', self, state, new_state) # treat as stale return False # If the state is one which we set and was meant to be passed # through to the downloader (valid_states), and the downloader # replied with something that was a response to a previous # download command, and state was also a part of valid_states, # but the saved state and the new state do not match # then it means the message is stale. # # Have a think about why this is true: when you set a state, # which is authoritative, to the downloader you expect it # to reply with that same state. If they do not match then it # means the message is stale. # # The exception to this rule is if the downloader replies with # an error state, or if downloading has transitioned to finished # state. # # This also does not apply to any state which we set on the # downloader via a restore command. A restore command before # a pause/resume/cancel will work as intended, and no special # trickery is required. A restore command which happens after # a pause/resume/cancel is void, so no work is required. # # I hope this makes sense and is clear! valid_states = (u'downloading', u'paused', u'stopped', u'uploading-paused', u'finished') if (cmd_done and state in valid_states and new_state in valid_states and state != new_state): if not (state == u'downloading' and new_state == u'finished'): logging.debug('self = %s STALE. ' 'Saved state %s, got state %s. Discarding.', self, state, new_state) return False # We are updating! Reset the status_updates_frozen flag. self.status_updates_frozen = False # We have something to update: update the last updated timestamp. self.last_update = now was_finished = self.is_finished() old_filename = self.get_filename() self.before_changing_rates() self.update_status_attributes(data) self.after_changing_rates() # Store the time the download finished finished = self.is_finished() and not was_finished name_changed = self.get_filename() != old_filename file_migrated = (self.is_finished() and name_changed) if ((self.get_state() == u'uploading' and not self.manualUpload and (app.config.get(prefs.LIMIT_UPLOAD_RATIO) and self.get_upload_ratio() > app.config.get(prefs.UPLOAD_RATIO)))): self.stop_upload() self.signal_change() if finished: for item in self.item_list: item.on_download_finished() elif file_migrated: self._file_migrated(old_filename) elif name_changed and old_filename and self.metainfo is not None: # update the torren title; happens with magnet URLs since we # don't have a real one when the download starts. The # old_filename check is to prevent things with existing titles # from being renamed (#18656). new_title = util.get_name_from_torrent_metadata(self.metainfo) for item in self.item_list: if item.torrent_title is None: item.torrent_title = new_title item.signal_change() return True