defmodule Xmeta.Xapi.View do defmacro __using__(opts) do unless opts[:title], do: raise("plaease set :title in Module: #{__MODULE__}") quote bind_quoted: [opts: opts] do Xmeta.Xapi.Env.put_module(__MODULE__, :xpi_api) if opts[:schema] do use Params.Schema, Xmeta.Xapi.View.make_schema(opts[:schema]) end @config opts def get_context_data(conn, params) do %{} end def call(conn, params) do {valid?, changes, errors} = valid_schema(conn,params) ctx = %{conn: conn} if valid? do ctx = ctx |> put_in([:data],changes) rsp = Xmeta.Xapi.View.check_middleware(ctx, params, __MODULE__) if rsp[:status] == 0, do: get_context_data(ctx, params), else: rsp else %{status: 400, data: [], msg: Xmeta.Xapi.View.make_errors(errors)} end end def config, do: @config defp get_schema, do: @config[:schema] defp valid_schema(conn, params) do schema = get_schema() unless schema do {true, params, []} else %Ecto.Changeset{valid?: valid?, changes: changes, errors: errors} = __MODULE__.from(params) {valid?,changes,errors} end end def get_middleware() do config = config() middleware = config[:middleware] if middleware, do: middleware, else: [] end defoverridable get_context_data: 2, call: 2, valid_schema: 2,get_middleware: 0 end end def make_schema(schema) do Enum.reduce(Map.to_list(schema), %{}, fn(x,acc) -> {key,data} = x if is_atom(data) do put_in(acc,[key],data) else data = for x <- data, check_key?(x), do: x put_in(acc,[key],data) end end) end defp check_key?(c) do {key,_} = c if key in [:name,:des] do false else true end end def make_errors(errors) do for x <- errors do {name,{msg,_}} = x %{} |> put_in([name],msg) end end def check_middleware(ctx, params, module) do mids = get_module_middleware(module) Enum.reduce(mids,%{status: 0, data: [], msg: ""}, fn(m,acc) -> if acc[:status] != 0 do acc else m.call(ctx,params) end end) end defp get_module_middleware(module) do slist = Module.split(module) site_mod = get_module_root(slist,1) router_mod = get_module_root(slist,2) site_mod.get_middleware() ++ router_mod.get_middleware() ++ module.get_middleware() end defp get_module_root(slist, num) do new_slist = for x <- 0..num do Enum.at(slist,x) end Module.concat(new_slist) end end