コード例 #1
0
    def save_resume_data(self, mod):
        """Save the resume data of the mod that will allow a faster restart in the future."""
        if not mod.torrent_handle.is_valid():
            Logger.error('save_resume_data: mod is not valid')
            return

        if not mod.torrent_handle.has_metadata():
            Logger.error('save_resume_data: mod has no metadata')
            return

        if not mod.can_save_resume_data:
            Logger.error('save_resume_data: mod cannot save resume data')
            return

        Logger.info('Sync: saving fast-resume metadata for mod {}'.format(
            mod.foldername))

        # Save data that could come in handy in the future to a metadata file
        # Set resume data for quick checksum check
        resume_data = libtorrent.bencode(
            mod.torrent_handle.write_resume_data())
        metadata_file = MetadataFile(mod.foldername)
        metadata_file.read_data(ignore_open_errors=False)
        metadata_file.set_torrent_resume_data(resume_data)
        metadata_file.write_data()
コード例 #2
0
def set_torrent_complete(mod):
    metadata_file = MetadataFile(mod.foldername)
    metadata_file.read_data(ignore_open_errors=True)
    metadata_file.set_dirty(False)
    metadata_file.set_torrent_url(mod.torrent_url)
    metadata_file.set_torrent_content(mod.torrent_content)
    metadata_file.set_torrent_resume_data('')

    metadata_file.set_force_creator_complete(True)
    metadata_file.write_data()
コード例 #3
0
    def torrent_finished_hook(self, mod):
        """Hook that is called when a torrent has been successfully and fully downloaded.
        This hook then removes any superfluous files in the directory and updates
        the metadata file.

        Return whether then mod has been synced successfully and no superfluous
        files are present in the directory.
        """
        if not mod.torrent_handle.has_metadata():
            Logger.error('Finished_hook: torrent {} has no metadata!'.format(
                mod.foldername))
            return False

        metadata_file = MetadataFile(mod.foldername)
        metadata_file.read_data(ignore_open_errors=False)

        # Remove unused files
        torrent_info = mod.torrent_handle.get_torrent_info()
        files_list = [
            entry.path.decode('utf-8') for entry in torrent_info.files()
        ]
        cleanup_successful = check_mod_directories(files_list,
                                                   mod.parent_location,
                                                   on_superfluous='remove')

        # Workaround. This should be moved to some kind of Mod class method or something...
        mod.files_list = files_list
        '''
        # Removed for now because we already have the original torrent file downloaded
        # and we don't need to artificially recreate it.

        # Recreate the torrent file and store it in the metadata file for future checks
        recreated_torrent = libtorrent.create_torrent(torrent_info)
        bencoded_recreated_torrent = libtorrent.bencode(recreated_torrent.generate())
        metadata_file.set_torrent_content(bencoded_recreated_torrent)
        '''

        if not cleanup_successful:
            Logger.info(
                "Could not perform mod {} cleanup. Marking torrent as dirty.".
                format(mod.foldername))
            metadata_file.set_dirty(True)
            metadata_file.write_data()

            return False
        else:
            metadata_file.set_dirty(False)
            metadata_file.write_data()

        return True
コード例 #4
0
    def prepare_libtorrent_params(self,
                                  mod,
                                  force_sync=False,
                                  just_seed=False):
        """Prepare mod for download over bittorrent.
        This effectively downloads the .torrent file if its contents are not
        already cached.
        Also set all the parameters required by libtorrent.
        """

        # TODO: Add the check: mod name == torrent directory name

        # === Metadata handling ===
        metadata_file = MetadataFile(mod.foldername)
        metadata_file.read_data(
            ignore_open_errors=True
        )  # In case the mod does not exist, we would get an error

        # Clear the force clean flag
        metadata_file.set_force_creator_complete(False)

        # A little bit of a workaround. If we intend to seed, we can assume the data is all right.
        # This way, if the torrent is closed before checking_resume_data is finished, and the post-
        # download hook is not fired, the torrent is not left in a state marked as dirty.
        if not just_seed and not force_sync:
            metadata_file.set_dirty(
                True
            )  # Set as dirty in case this process is not terminated cleanly

        # If the torrent url changed, invalidate the resume data
        old_torrent_url = metadata_file.get_torrent_url()
        if old_torrent_url != mod.torrent_url or force_sync:
            metadata_file.set_torrent_resume_data('')
            metadata_file.set_torrent_content('')
            # print "Setting torrent url to {}".format(mod.torrent_url)
            metadata_file.set_torrent_url(mod.torrent_url)

        metadata_file.write_data()
        # End of metadata handling

        # === Torrent parameters ===
        params = {
            'save_path': encode_utf8(mod.parent_location),
            'storage_mode': libtorrent.storage_mode_t.
            storage_mode_allocate,  # Reduce fragmentation on disk
            'flags': torrent_utils.create_add_torrent_flags(just_seed)
        }

        torrent_info, torrent_content = self.get_mod_torrent_metadata(
            mod, metadata_file)
        params['ti'] = torrent_info

        # Cache it for future requests
        metadata_file.set_torrent_content(torrent_content)
        metadata_file.write_data()

        # Add optional resume data
        resume_data = metadata_file.get_torrent_resume_data()
        if resume_data:  # Quick resume torrent from data saved last time the torrent was run
            params['resume_data'] = resume_data

        mod.libtorrent_params = params

        if not just_seed:
            # Ensure the mod directory is correct (no bad links and read-write)
            # This should have been already done with preparer.py but it doesn't
            # hurt to do that again in case something changed in the meantime.
            torrent_utils.prepare_mod_directory(mod.get_full_path())