Edit

kc3-lang/kc3/httpd/fx/app/controllers

Branch :

  • fx_controller.kc3
  • defmodule FXController do
    
      require File
      require HTTP
      require List
      require Str
    
      def file_index = fn {
        (path, target) { file_index(path, target, path, []) }
        ([], target, dir, acc) { List.reverse(acc) }
        ([file | rest], target, dir, acc) {
          path = dir + file
          if (Str.starts_with?(file, ".") ||
              File.is_directory?(path)) do
            file_index(rest, target, dir, acc)
          else
            url = Str.slice(path, 1, -1)
            item = %{type: :file,
                     url: url,
                     name: file,
                     path: path}
            file_index(rest, target, dir, [item | acc])
          end
        }
        (path, target, dir, acc) {
          if (type(path) == Str) do
            file_index(List.sort(File.list(path)), target, dir, acc)
          end
        }
      }
    
      def directory_index = fn {
        (path, target) { directory_index(path, target, path, []) }
        ([], target, dir, acc) { List.reverse(acc) }
        ([file | rest], target, dir, acc) {
          path = dir + file
          if (Str.starts_with?(file, ".") ||
              ! File.is_directory?(path)) do
            directory_index(rest, target, dir, acc)
          else
            url = Str.slice(path, 1, -1)
            if File.is_directory?(path) do
              items = []
              item = %{type: :dir,
                       url: url,
                       name: file,
                       items: items}
              directory_index(rest, target, dir, [item | acc])
            end
          end
        }
        (path, target, dir, acc) {
          if (type(path) == Str) do
            directory_index(List.sort(File.list(path)), target, dir, acc)
          end
        }
      }
    
      def show_file = fn (path, url) {
        if (File.exists?(path)) do
          if (File.is_directory?(path)) do
            slash = if Str.ends_with?(path, "/") do "" else "/" end
            path = path + slash
            menu_index = directory_index(path, path)
            menu = FXView.render_menu_index(menu_index)
            index = file_index(path, path)
            file = FXView.render_index(index)
          else
            menu_path = File.dirname(path)
            menu_index = directory_index(menu_path, path)
            menu = FXView.render_menu_index(menu_index)
            file = FXView.render_show_file_preview(path, :full)
          end
          properties = Fx.property_index(path)
          tags = Fx.tag_index(path)
          properties = FXView.render_properties(properties)
          page = FXView.render_show_file(path, menu, file, properties)
          body = LayoutView.render(path, page, url)
          %HTTP.Response{body: body}
        end
      }
    
      def fx_route = fn (request) {
        if (request.method == GET ||
            request.method == HEAD) &&
           (request.url == "/fx" ||
            Str.starts_with?(request.url, "/fx/")) do
          path = "." + request.url
          show_file(path, request.url)
        end
      }
    
      def tag_create = fn (path, tag) {
        Fx.tag_add(path, tag)
        body = """
    <html>
      <head>
        <title>Tag create</title>
      </head>
      <body>
        <p><h1>Tag create</h1></p>
        <p>Tag : #{HTML.escape(inspect(tag))}</p>
        <p>Path : #{HTML.escape(inspect(path))}</p>
      </body>
    </html>
    """
        %HTTP.Response{body: body}
      }
    
      def tag_delete = fn (path, tag) {
        Fx.tag_remove(path, tag)
        body = """
    <html>
      <head>
        <title>Tag delete</title>
      </head>
      <body>
        <p><h1>Tag delete</h1></p>
        <p>Tag : #{HTML.escape(inspect(tag))}</p>
        <p>Path : #{HTML.escape(inspect(path))}</p>
      </body>
    </html>
    """
        %HTTP.Response{body: body}
      }
    
      def tags_route = fn (req) {
        ["", "tags", url] = Str.split(req.url, "/")                  
        path = "./fx" + req.url
          if (req.method == POST) do
            response = tag_create(path, tag)
          else
            if (req.method == DELETE) do
              response = tag_delete(path, tag)
            else
              error_405_page(req)
            end
          end
        end
      }
    
      def property_create = fn (path, property, value) {
        Fx.property_add(path, property, value)
        HTTPd.redirect_to("/" + path)
      }
    
      def property_delete = fn (path, property, value) {
        Fx.property_remove(path, property, value)
        HTTPd.redirect_to("/" + path)
      }
    
      def properties_route = fn (req) {
        url = if (req.url == "/properties/fx") do
          req.url + "/"
        else
          req.url
        end
        if Str.starts_with?(url, "/properties/fx/") do
          path = Str.slice(url, 12, -1)
          body = req.body
          property = body["property_key"]
          value = body["property_value"]
          if (property == void || value == void) do
            HTTPd.error_400_page(req)
          else
            if (req.method == POST) do
              property_create(path, property, value)
            else
              if (req.method == DELETE) do
                property_delete(path, property, value)
              else
                HTTPd.error_405_page(req)
              end
            end
          end
        else
          HTTPd.error_404_page(req)
        end
      }
    
    end