Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: try to add embed folder #60

Open
jinzhongjia opened this issue Jul 13, 2024 · 3 comments
Open

feat: try to add embed folder #60

jinzhongjia opened this issue Jul 13, 2024 · 3 comments

Comments

@jinzhongjia
Copy link
Collaborator

No description provided.

@hassandraga
Copy link
Member

Try this Zig version of vfs.py, I did not test it yet.

  1. Run python vfs.py "myFolder" "vfs.zig"
  2. Import vfs.zig in main.zig of the serve_a_folder example
  3. Set vfs as file the handler MyWindow.setFileHandler(vfs);

vfs.py:

import os
import sys

def generate_vfs_zig(directory, output_file):
    files = []
    index_files = {}

    for root, _, filenames in os.walk(directory):
        for filename in filenames:
            filepath = os.path.join(root, filename)
            relative_path = os.path.relpath(filepath, directory)
            # Ensure path starts with a slash
            relative_path = '/' + relative_path.replace('\\', '/')
            files.append((relative_path, filepath))

            # Check for index files
            if filename.startswith("index."):
                dir_path = os.path.dirname(relative_path)
                if dir_path not in index_files:
                    index_files[dir_path] = relative_path

    with open(output_file, 'w') as zig_file:
        zig_file.write('const std = @import("std");\n')
        zig_file.write('const webui = @import("webui");\n\n')

        zig_file.write('pub const VirtualFile = struct {\n')
        zig_file.write('    path: []const u8,\n')
        zig_file.write('    data: []const u8,\n')
        zig_file.write('    length: usize,\n')
        zig_file.write('};\n\n')

        zig_file.write('pub const virtual_files = []const VirtualFile{\n')

        for relative_path, filepath in files:
            with open(filepath, 'rb') as f:
                data = f.read()
                zig_file.write('    VirtualFile{\n')
                zig_file.write(f'        .path = "{relative_path}",\n')
                zig_file.write('        .data = &[_]u8{')
                zig_file.write(','.join(f'0x{byte:02x}' for byte in data))
                zig_file.write('},\n')
                zig_file.write(f'        .length = {len(data)},\n')
                zig_file.write('    },\n')

        zig_file.write('};\n\n')

        zig_file.write('pub const virtual_files_count = @sizeOf(virtual_files) / @sizeOf(virtual_files[0]);\n\n')

        zig_file.write('pub const index_files = []const struct {\n')
        zig_file.write('    dir_path: []const u8,\n')
        zig_file.write('    index_path: []const u8,\n')
        zig_file.write('}{\n')
        for dir_path, index_path in index_files.items():
            zig_file.write(f'    .{{ "{dir_path}/", "{index_path}" }},\n')
        zig_file.write('};\n\n')

        zig_file.write('pub fn virtualFileSystem(path: []const u8) ?[]const u8 {\n')
        zig_file.write('    for (virtual_files) |file| {\n')
        zig_file.write('        if (std.mem.eql(u8, file.path, path)) {\n')
        zig_file.write('            return file.data;\n')
        zig_file.write('        }\n')
        zig_file.write('    }\n')
        zig_file.write('    return null;\n')
        zig_file.write('}\n\n')

        zig_file.write('pub fn vfs(path: []const u8) ?[]const u8 {\n')
        zig_file.write('    const file_data = virtualFileSystem(path);\n\n')

        zig_file.write('    if (file_data) |data| {\n')
        zig_file.write('        const content_type = webui.getMimeType(path);\n')
        zig_file.write('        const header = std.fmt.bufPrint(\n')
        zig_file.write('            "HTTP/1.1 200 OK\\r\\nContent-Type: {s}\\r\\nContent-Length: {d}\\r\\nCache-Control: no-cache\\r\\n\\r\\n",\n')
        zig_file.write('            .{content_type, data.len}\n')
        zig_file.write('        );\n')
        zig_file.write('        return header ++ data;\n')
        zig_file.write('    } else {\n')
        zig_file.write('        // Check for index file redirection\n')
        zig_file.write('        var redirect_path = std.mem.concat(u8, path, "/");\n')
        zig_file.write('        for (index_files) |entry| {\n')
        zig_file.write('            if (std.mem.eql(u8, entry.dir_path, redirect_path)) {\n')
        zig_file.write('                const header = std.fmt.bufPrint(\n')
        zig_file.write('                    "HTTP/1.1 302 Found\\r\\nLocation: {s}\\r\\nCache-Control: no-cache\\r\\n\\r\\n",\n')
        zig_file.write('                    .{entry.index_path}\n')
        zig_file.write('                );\n')
        zig_file.write('                return header;\n')
        zig_file.write('            }\n')
        zig_file.write('        }\n')
        zig_file.write('        return null;\n')
        zig_file.write('    }\n')
        zig_file.write('}\n')

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print(f'Usage: {sys.argv[0]} <directory> <output_zig>')
        sys.exit(1)

    directory = sys.argv[1]
    output_zig = sys.argv[2]
    generate_vfs_zig(directory, output_zig)
    print(f'Generated {output_zig} from {directory}')

@jinzhongjia
Copy link
Collaborator Author

A better solution can be achieved through zig theory, but there may not be time recently

@jinzhongjia
Copy link
Collaborator Author

And I think this is not a priority to solve, because zig itself supports embedded files, but does not support embedded folders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants