Esempio n. 1
0
def save_backup():
    """Save the backup file."""
    # We generate it from scratch, since that's the only way to remove
    # files.
    new_zip_data = BytesIO()
    new_zip = ZipFile(new_zip_data, 'w', compression=ZIP_LZMA)

    maps = [
        item.p2c
        for item in
        UI['back_details'].items
    ]

    if not maps:
        messagebox.showerror(
            gettext('BEE2 Backup'),
            gettext('No maps were chosen to backup!'),
        )
        return

    copy_loader.set_length('COPY', len(maps))

    with copy_loader:
        for p2c in maps:  # type: P2C
            old_zip = p2c.zip_file
            map_path = p2c.filename + '.p2c'
            scr_path = p2c.filename + '.jpg'
            if scr_path in zip_names(old_zip):
                with zip_open_bin(old_zip, scr_path) as f:
                    new_zip.writestr(scr_path, f.read())

            # Copy the map as bytes, so encoded characters are transfered
            # unaltered.
            with zip_open_bin(old_zip, map_path) as f:
                new_zip.writestr(map_path, f.read())
            copy_loader.step('COPY')

    new_zip.close()  # Finalize zip

    with open(BACKUPS['backup_path'], 'wb') as backup:
        backup.write(new_zip_data.getvalue())
    BACKUPS['unsaved_file'] = new_zip_data

    # Remake the zipfile object, so it's open again.
    BACKUPS['backup_zip'] = new_zip = ZipFile(
        new_zip_data,
        mode='w',
        compression=ZIP_LZMA,
    )

    # Update the items, so they use this zip now.
    for p2c in maps:
        p2c.zip_file = new_zip
Esempio n. 2
0
def save_backup():
    """Save the backup file."""
    # We generate it from scratch, since that's the only way to remove
    # files.
    new_zip_data = BytesIO()
    new_zip = ZipFile(new_zip_data, 'w', compression=ZIP_LZMA)

    maps = [
        item.p2c
        for item in
        UI['back_details'].items
    ]

    if not maps:
        messagebox.showerror(
            _('BEE2 Backup'),
            _('No maps were chosen to backup!'),
        )
        return

    copy_loader.set_length('COPY', len(maps))

    with copy_loader:
        for p2c in maps:  # type: P2C
            old_zip = p2c.zip_file
            map_path = p2c.filename + '.p2c'
            scr_path = p2c.filename + '.jpg'
            if scr_path in zip_names(old_zip):
                with zip_open_bin(old_zip, scr_path) as f:
                    new_zip.writestr(scr_path, f.read())

            # Copy the map as bytes, so encoded characters are transfered
            # unaltered.
            with zip_open_bin(old_zip, map_path) as f:
                new_zip.writestr(map_path, f.read())
            copy_loader.step('COPY')

    new_zip.close()  # Finalize zip

    with open(BACKUPS['backup_path'], 'wb') as backup:
        backup.write(new_zip_data.getvalue())
    BACKUPS['unsaved_file'] = new_zip_data

    # Remake the zipfile object, so it's open again.
    BACKUPS['backup_zip'] = new_zip = ZipFile(
        new_zip_data,
        mode='w',
        compression=ZIP_LZMA,
    )

    # Update the items, so they use this zip now.
    for p2c in maps:
        p2c.zip_file = new_zip
Esempio n. 3
0
def do_copy(zip_list, done_files):
    cache_path = os.path.abspath('../cache/')
    music_samp = os.path.abspath('../sounds/music_samp/')
    shutil.rmtree(cache_path, ignore_errors=True)
    shutil.rmtree(music_samp, ignore_errors=True)

    img_loc = os.path.join('resources', 'bee2')
    music_loc = os.path.join('resources', 'music_samp')
    for zip_path in zip_list:
        if os.path.isfile(zip_path):
            zip_file = ZipFile(zip_path)
        else:
            zip_file = FakeZip(zip_path)
        with zip_file:
            for path in zip_names(zip_file):
                loc = os.path.normcase(path)
                if not loc.startswith("resources"):
                    continue
                # Don't re-extract images
                if loc.startswith(img_loc):
                    continue
                if loc.startswith(music_loc):
                    dest_path = os.path.join(music_samp,
                                             os.path.relpath(path, music_loc))
                    os.makedirs(os.path.dirname(dest_path), exist_ok=True)
                    with zip_open_bin(zip_file, path) as src:
                        with open(dest_path, 'wb') as dest:
                            shutil.copyfileobj(src, dest)
                else:
                    zip_file.extract(path, path=cache_path)
                with done_files.get_lock():
                    done_files.value += 1
Esempio n. 4
0
def do_copy(zip_list, done_files):
    cache_path = os.path.abspath('../cache/')
    music_samp = os.path.abspath('../sounds/music_samp/')
    shutil.rmtree(cache_path, ignore_errors=True)
    shutil.rmtree(music_samp, ignore_errors=True)

    img_loc = os.path.join('resources', 'bee2')
    music_loc = os.path.join('resources', 'music_samp')
    for zip_path in zip_list:
        if os.path.isfile(zip_path):
            zip_file = ZipFile(zip_path)
        else:
            zip_file = FakeZip(zip_path)
        with zip_file:
            for path in zip_names(zip_file):
                loc = os.path.normcase(path)
                if not loc.startswith("resources"):
                    continue
                # Don't re-extract images
                if loc.startswith(img_loc):
                    continue
                if loc.startswith(music_loc):
                    dest_path = os.path.join(
                        music_samp,
                        os.path.relpath(path, music_loc)
                    )
                    os.makedirs(os.path.dirname(dest_path), exist_ok=True)
                    with zip_open_bin(zip_file, path) as src:
                        with open(dest_path, 'wb') as dest:
                            shutil.copyfileobj(src, dest)
                else:
                    zip_file.extract(path, path=cache_path)
                with done_files.get_lock():
                    done_files.value += 1
Esempio n. 5
0
def restore_maps(maps: List[P2C]):
    """Copy the given maps to the game."""
    game_dir = BACKUPS['game_path']
    if game_dir is None:
        LOGGER.warning('No game selected to restore from?')
        return

    copy_loader.set_length('COPY', len(maps))
    with copy_loader:
        for p2c in maps:
            back_zip = p2c.zip_file
            scr_path = p2c.filename + '.jpg'
            map_path = p2c.filename + '.p2c'
            abs_scr = os.path.join(game_dir, scr_path)
            abs_map = os.path.join(game_dir, map_path)
            if (
                    os.path.isfile(abs_scr) or
                    os.path.isfile(abs_map)
                    ):
                if not messagebox.askyesno(
                        title='Overwrite File?',
                        message=gettext('This map is already in the game directory.'
                                  'Do you wish to overwrite it? '
                                  '({})').format(p2c.title),
                        parent=window,
                        icon=messagebox.QUESTION,
                        ):
                    copy_loader.step('COPY')
                    continue

            if scr_path in zip_names(back_zip):
                    with zip_open_bin(back_zip, scr_path) as src:
                        with open(abs_scr, 'wb') as dest:
                            shutil.copyfileobj(src, dest)

            with zip_open_bin(back_zip, map_path) as src:
                with open(abs_map, 'wb') as dest:
                    shutil.copyfileobj(src, dest)

            new_item = p2c.copy()
            new_item.zip_file = FakeZip(game_dir)
            BACKUPS['game'].append(new_item)
            copy_loader.step('COPY')

    refresh_game_details()
Esempio n. 6
0
def restore_maps(maps: List[P2C]):
    """Copy the given maps to the game."""
    game_dir = BACKUPS['game_path']
    if game_dir is None:
        LOGGER.warning('No game selected to restore from?')
        return

    copy_loader.set_length('COPY', len(maps))
    with copy_loader:
        for p2c in maps:
            back_zip = p2c.zip_file
            scr_path = p2c.filename + '.jpg'
            map_path = p2c.filename + '.p2c'
            abs_scr = os.path.join(game_dir, scr_path)
            abs_map = os.path.join(game_dir, map_path)
            if (
                    os.path.isfile(abs_scr) or
                    os.path.isfile(abs_map)
                    ):
                if not messagebox.askyesno(
                        title='Overwrite File?',
                        message=_('This map is already in the game directory.'
                                  'Do you wish to overwrite it? '
                                  '({})').format(p2c.title),
                        parent=window,
                        icon=messagebox.QUESTION,
                        ):
                    copy_loader.step('COPY')
                    continue

            if scr_path in zip_names(back_zip):
                    with zip_open_bin(back_zip, scr_path) as src:
                        with open(abs_scr, 'wb') as dest:
                            shutil.copyfileobj(src, dest)

            with zip_open_bin(back_zip, map_path) as src:
                with open(abs_map, 'wb') as dest:
                    shutil.copyfileobj(src, dest)

            new_item = p2c.copy()
            new_item.zip_file = FakeZip(game_dir)
            BACKUPS['game'].append(new_item)
            copy_loader.step('COPY')

    refresh_game_details()
Esempio n. 7
0
    def from_file(cls, path, zip_file):
        """Initialise from a file.

        path is the file path for the map inside the zip, without extension.
        zip_file is either a ZipFile or FakeZip object.
        """
        # Some P2Cs may have non-ASCII characters in descriptions, so we
        # need to read it as bytes and convert to utf-8 ourselves - zips
        # don't convert encodings automatically for us.
        try:
            with zip_open_bin(zip_file, path + '.p2c') as file:
                props = Property.parse(
                    # Decode the P2C as UTF-8, and skip unknown characters.
                    # We're only using it for display purposes, so that should
                    # be sufficent.
                    TextIOWrapper(
                        file,
                        encoding='utf-8',
                        errors='replace',
                    ),
                    path,
                )
        except KeyValError:
            # Silently fail if we can't parse the file. That way it's still
            # possible to backup.
            LOGGER.warning('Failed parsing puzzle file!', path, exc_info=True)
            props = Property('portal2_puzzle', [])
            title = None
            desc = _('Failed to parse this puzzle file. It can still be backed up.')
        else:
            props = props.find_key('portal2_puzzle', [])
            title = props['title', None]
            desc = props['description', _('No description found.')]



        if title is None:
            title = '<' + path.rsplit('/', 1)[-1] + '.p2c>'

        return cls(
            filename=os.path.basename(path),
            zip_file=zip_file,
            title=title,
            desc=desc,
            is_coop=srctools.conv_bool(props['coop', '0']),
            create_time=Date(props['timestamp_created', '']),
            mod_time=Date(props['timestamp_modified', '']),
        )
Esempio n. 8
0
    def from_file(cls, path, zip_file):
        """Initialise from a file.

        path is the file path for the map inside the zip, without extension.
        zip_file is either a ZipFile or FakeZip object.
        """
        # Some P2Cs may have non-ASCII characters in descriptions, so we
        # need to read it as bytes and convert to utf-8 ourselves - zips
        # don't convert encodings automatically for us.
        try:
            with zip_open_bin(zip_file, path + '.p2c') as file:
                props = Property.parse(
                    # Decode the P2C as UTF-8, and skip unknown characters.
                    # We're only using it for display purposes, so that should
                    # be sufficent.
                    TextIOWrapper(
                        file,
                        encoding='utf-8',
                        errors='replace',
                    ),
                    path,
                )
        except KeyValError:
            # Silently fail if we can't parse the file. That way it's still
            # possible to backup.
            LOGGER.warning('Failed parsing puzzle file!', path, exc_info=True)
            props = Property('portal2_puzzle', [])
            title = None
            desc = _('Failed to parse this puzzle file. It can still be backed up.')
        else:
            props = props.find_key('portal2_puzzle', [])
            title = props['title', None]
            desc = props['description', _('No description found.')]



        if title is None:
            title = '<' + path.rsplit('/', 1)[-1] + '.p2c>'

        return cls(
            filename=os.path.basename(path),
            zip_file=zip_file,
            title=title,
            desc=desc,
            is_coop=srctools.conv_bool(props['coop', '0']),
            create_time=Date(props['timestamp_created', '']),
            mod_time=Date(props['timestamp_modified', '']),
        )
Esempio n. 9
0
def save_backup():
    """Save the backup file."""
    # We generate it from scratch, since that's the only way to remove
    # files.
    new_zip_data = BytesIO()
    new_zip = ZipFile(new_zip_data, 'w', compression=ZIP_LZMA)

    maps = [
        item.p2c
        for item in
        UI['back_details'].items
    ]

    copy_loader.set_length('COPY', len(maps))

    with copy_loader:
        for p2c in maps:
            old_zip = p2c.zip_file
            map_path = p2c.path + '.p2c'
            scr_path = p2c.path + '.jpg'
            if scr_path in zip_names(old_zip):
                with zip_open_bin(old_zip, scr_path) as f:
                    new_zip.writestr(scr_path, f.read())

            with old_zip.open(map_path, 'r') as f:
                new_zip.writestr(map_path, f.read())
            copy_loader.step('COPY')

    new_zip.close()  # Finalize zip

    with open(BACKUPS['backup_path'], 'wb') as backup:
        backup.write(new_zip_data.getvalue())
    BACKUPS['unsaved_file'] = new_zip_data

    # Remake the zipfile object, so it's open again.
    BACKUPS['backup_zip'] = new_zip = ZipFile(
        new_zip_data,
        mode='w',
        compression=ZIP_LZMA,
    )

    # Update the items, so they use this zip now.
    for p2c in maps:
        p2c.zip_file = new_zip
Esempio n. 10
0
    def from_file(cls, path, zip_file):
        """Initialise from a file.

        path is the file path for the map inside the zip, without extension.
        zip_file is either a ZipFile or FakeZip object.
        """
        # Some P2Cs may have non-ASCII characters in descriptions, so we
        # need to read it as bytes and convert to utf-8 ourselves - zips
        # don't convert encodings automatically for us.
        with zip_open_bin(zip_file, path + '.p2c') as file:
            props = Property.parse(
                # Decode the P2C as UTF-8, and skip unknown characters.
                # We're only using it for display purposes, so that should
                # be sufficent.
                EncodedFile(
                    file,
                    data_encoding='utf-8',
                    errors='replace',
                ),
                path,
            )
        props = props.find_key('portal2_puzzle', [])

        title = props['title', None]
        if title is None:
            title = '<' + path.rsplit('/', 1)[-1] + '.p2c>'

        return cls(
            path=path,
            zip_file=zip_file,
            title=title,
            desc=props['description', '...'],
            is_coop=utils.conv_bool(props['coop', '0']),
            create_time=Date(props['timestamp_created', '']),
            mod_time=Date(props['timestamp_modified', '']),
        )