Erlang/OTP Forums

Author Message

<  Erlyweb mailing list  ~  Porting Erlyweb to ewgi (Was:ErlyWeb dependencies and their

boz
Posted: Thu Jan 03, 2008 7:11 am Reply with quote
Joined: 01 Jan 2008 Posts: 5
Hi Kevin,

I was just looking into this tonight as well. I've attached what I'm
working with so far.

On Jan 2, 6:47 pm, "Kevin A. Smith" <ke...@hypotheticalabs.com> wrote:
> * yaws_args/yaws_headers - This looks pretty straightforward. We'd
> just need to replace yaws api calls with the corresponding ewgi calls.
> ewgi appears to be missing cookie support in ewgi_api but I think I
> could add that. Does this sound about right?

instead of yaws_arg going everywhere, I created a erlyweb_arg which
should be used throughout erlyweb and has an interface for both ewgi
and yaws.

> * erlyweb:out/1 -- I'm hung up on this one and looking for some ideas.
> Yaws calls this function directly for each request. Does ewgi have
> something we could shim in here in its place? I'm thinking of some
> sort of appmod that proxies yaws calls into Erlyweb.

I took this out of the erlyweb module and put it in
erlyweb_interface_yaws. the entry point into request parsing for
erlyweb is now erlyweb:handle_request/3. I started an
erlyweb_interface_ewgi which will (eventually) convert erlyweb's
response into something that ewgi can handle ( strip out all the ehtml
and header-specific stuff ).

a lot more needs to be done, just want to put it out there for review.

-Adam

Index: erlyweb_forms.erl
===================================================================
--- erlyweb_forms.erl (revision 228)
+++ erlyweb_forms.erl (working copy)
@@ -35,7 +35,7 @@
%% @spec to_recs(A::arg() | [{ParamName::string(),
ParamVal::term()}],
%% [{Prefix::string(), Model::atom()}]) -> [Record::tuple()]
to_recs(A, ModelDescs) when is_tuple(A), element(1, A) == arg ->
- to_recs(yaws_api:parse_post(A), ModelDescs);
+ to_recs(erlyweb_arg:parse_post(A), ModelDescs);
to_recs(Params, ModelDescs) ->
Models =
[{Prefix, Model, Model:new()} || {Prefix, Model} <- ModelDescs],
@@ -95,7 +95,7 @@
%% Fun::function()) -> {Values::[term()], Errors::[term()]} |
%% exit({missing_param, Field})
validate(A, Fields, Fun) when is_tuple(A), element(1, A) == arg ->
- validate(yaws_api:parse_post(A), Fields, Fun);
+ validate(erlyweb_arg:parse_post(A), Fields, Fun);
validate(Params, Fields, Fun) ->
lists:foldr(
fun(Field, Acc) ->
@@ -115,7 +115,7 @@
%% Fun::function()) -> {Vals, Errs} | exit({missing_params,
[string()]}) |
%% exit({unexpected_params, proplist()}) | exit({unexpected_param,
string()})
validate1(A, Fields, Fun) when is_tuple(A), element(1, A) == arg ->
- validate1(yaws_api:parse_post(A), Fields, Fun);
+ validate1(erlyweb_arg:parse_post(A), Fields, Fun);
validate1(Params, Fields, Fun) ->
validate1_1(Params, Fields, Fun, {[], []}).

Index: erlyweb_arg.erl
===================================================================
--- erlyweb_arg.erl (revision 0)
+++ erlyweb_arg.erl (revision 0)
@@ -0,0 +1,38 @@
+-module(erlyweb_arg).
+-export([create/2]).
+-export([opaque/1,appmoddata/1,server_path/1,method/1,parse_post/1]).
+-export([props/1,prop_insert/2,prop_find/2]).
+-export([app_data/1,app_data/2,app_controller/1,app_controller/2]).
+
+create(Mod,Arg) ->
+ {Mod,Arg,[]}.
+appmoddata({Mod,Arg,_}) ->
+ Mod:appmoddata(Arg).
+server_path({Mod,Arg,_}) ->
+ Mod:server_path(Arg).
+method({Mod,Arg,_}) ->
+ Mod:method(Arg).
+parse_post({Mod,Arg,_}) ->
+ Mod:parse_post(Arg).
+
+props({_,_,O}) ->
+ O.
+prop_insert({Mod,Arg,O},{Key,Val}) ->
+ O2 = case proplists:is_defined(Key,O) of
+ true -> proplists:delete(Key,O);
+ _ -> O
+ end,
+ {Mod,Arg,[{Key,Val}|O2]}.
+prop_find({_,_,O},Key) ->
+ proplists:lookup(Key,O).
+
+app_data(Arg) ->
+ prop_find(Arg,app_data_module).
+app_data(Arg,AppData) ->
+ prop_insert(Arg,{app_data_module,AppData}).
+
+app_controller(Arg) ->
+ prop_find(Arg,app_controller_module).
+app_controller(Arg,AppData) ->
+ prop_insert(Arg,{app_controller_module,AppData}).
+
Index: erlyweb_interface_ewgi.erl
===================================================================
--- erlyweb_interface_ewgi.erl (revision 0)
+++ erlyweb_interface_ewgi.erl (revision 0)
@@ -0,0 +1,12 @@
+-module(erlyweb_interface_ewgi).
+
+handle_req(Env,StartResp) ->
+ Arg = erlyweb_arg_ewgi:create(Env),
+ { Arg2 , AppController , AppData } =
erlyweb:prepare_request(Arg),
+ Resp = erlyweb:handle_request(Arg2,AppController,AppData),
+ handle_response(Env,StartResp,Resp).
+
+% filter out all the ehtml/yaws return stuff (ewgi-ify the response).
+handle_response(Env,StartResp,Resp) ->
+ todo.
+
Index: erlyweb_arg_yaws.erl
===================================================================
--- erlyweb_arg_yaws.erl (revision 0)
+++ erlyweb_arg_yaws.erl (revision 0)
@@ -0,0 +1,15 @@
+-module(erlyweb_arg_yaws).
+-export([create/1]).
+-export([appmoddata/1,server_path/1,method/1,parse_post/1]).
+
+create(A) ->
+ erlyweb_arg:create(?MODULE,A).
+appmoddata(A) ->
+ yaws_arg:appmoddata(A).
+server_path(A) ->
+ yaws_arg:server_path(A).
+method(A) ->
+ yaws_arg:method(A).
+parse_post(A) ->
+ yaws_api:parse_post(A).
+
Index: erlyweb_util.erl
===================================================================
--- erlyweb_util.erl (revision 228)
+++ erlyweb_util.erl (working copy)
@@ -11,8 +11,7 @@
-module(erlyweb_util).
-author("Yariv Sadan (yarivsblog@gmail.com, http://yarivsblog.com").
-export([log/5, create_app/2, create_component/3,
- get_url_prefix/1,
- get_cookie/2, indexify/2]).
+ get_url_prefix/1, indexify/2]).

-define(Debug(Msg, Params), log(?MODULE, ?LINE, debug, Msg, Params)).
-define(Info(Msg, Params), log(?MODULE, ?LINE, info, Msg, Params)).
@@ -234,17 +233,8 @@
lists:dropwhile(
fun($?) -> true;
(_) -> false
- end, yaws_arg:appmoddata(A)).
+ end, erlyweb_arg:appmoddata(A)).

-
-%% @doc Get the cookie's value from the arg.
-%% @equiv yaws_api:find_cookie_val(Name, yaws_headers:cookie(A))
-%%
-%% @spec get_cookie(Name::string(), A::arg()) -> string()
-get_cookie(Name, A) ->
- yaws_api:find_cookie_val(
- Name, yaws_headers:cookie(A)).
-
%% @doc Translate requests such as '/foo/bar' to '/foo/index/bar' for
the given
%% list of components. This function is useful for rewriting the Arg
in the
%% app controller prior to handling incoming requests.
@@ -254,14 +244,14 @@
%%
%% @spec indexify(A::arg(), ComponentNames::[string()]) -> arg()
indexify(A, ComponentNames) ->
- Appmod = yaws_arg:appmoddata(A),
- Sp = yaws_arg:server_path(A),
+ Appmod = erlyweb_arg:appmoddata(A),
+ Sp = erlyweb_arg:server_path(A),

Appmod1 = indexify1(Appmod, ComponentNames),
- A1 = yaws_arg:appmoddata(A, Appmod1),
+ A1 = erlyweb_arg:appmoddata(A, Appmod1),

{SpRoot, _} = lists:split(length(Sp) - length(Appmod), Sp),
- yaws_arg:server_path(A1, SpRoot ++ Appmod1).
+ erlyweb_arg:server_path(A1, SpRoot ++ Appmod1).


indexify1(S1, []) -> S1;
Index: erlyweb.erl
===================================================================
--- erlyweb.erl (revision 228)
+++ erlyweb.erl (working copy)
@@ -145,52 +145,6 @@
compile(AppDir, Options) ->
erlyweb_compile:compile(AppDir, Options).

-
-%% @doc This is the out/1 function that Yaws calls when passing
-%% HTTP requests to the ErlyWeb appmod.
-%%
-%% @spec out(A::yaws_arg()) -> ret_val()
-out(A) ->
- AppName = get_app_name(A),
- AppData = erlyweb_compile:get_app_data_module(AppName),
- AppController =
- case catch AppData:get_controller() of
- {'EXIT', {undef, _}} ->
- exit({no_application_data,
- "Did you forget to call erlyweb:compile(AppDir) "
- "or add the app's previously compiled .beam "
- "files to the Erlang code path?"});
- Other1 ->
- Other1
- end,
- case AppData:auto_compile() of
- false -> ok;
- {true, Options} ->
- auto_compile(A, AppData, Options)
- end,
-
- out(yaws_arg:add_to_opaque(
- A, {app_data_module, AppData}), AppController).
-
-%% @doc This function is useful for embedding the result of a
'phased'
-%% ErlyWeb rendering in an ErlyWeb component from the same
application,
-%% but using a different app controller.
-%%
-%% This function was originally designed to simplify Facebook app
development
-%% with ErlyWeb using Erlang2Facebook
-%% (http://code.google.com/p/erlang2facebook).
-%% In erlang2facebook, the fb_canvas component intercepts requests
-%% from Facebook and authenticates them. After authentication, it may
be
-%% useful to start a new ErlyWeb "flow" using an alternative app
controller
-%% and display the result in of this flow the output of fb_canvas.
-%%
-%% @spec out(A::arg(), AppController::atom()) -> term()
-out(A, AppController) ->
- AppData = proplists:get_value(app_data_module,
yaws_arg:opaque(A)),
- handle_request(A,
- AppController, AppController:hook(A),
- AppData).
-
%% checks that at least 3 seconds have passed since the last
compilation
%% and that the request doesn't match the optional
auto_compile_exclude
%% value.
@@ -204,7 +158,7 @@
case lists:keysearch(auto_compile_exclude, 1,
Options) of
{value, {_, Val}} ->
- case string:str(yaws_arg:appmoddata(A),
+ case string:str(erlyweb_arg:appmoddata(A),
Val) of
1 -> ok;
_ -> auto_compile1(AppData, Options)
@@ -222,6 +176,33 @@
Err -> exit(Err)
end.

+prepare_request(A) ->
+ AppName = get_app_name(Arg),
+ AppData = erlyweb_compile:get_app_data_module(AppName),
+ AppController =
+ case catch AppData:get_controller() of
+ {'EXIT', {undef, _}} ->
+ exit({no_application_data,
+ "Did you forget to call erlyweb:compile(AppDir) "
+ "or add the app's previously compiled .beam "
+ "files to the Erlang code path?"});
+ Other1 ->
+ Other1
+ end,
+ case AppData:auto_compile() of
+ false -> ok;
+ {true, Options} ->
+ auto_compile(A, AppData, Options)
+ end,
+ A2 = erlyweb_arg:app_data(A,AppData),
+ A3 = erlyweb_arg:app_controller(A,AppController),
+ { A3 , AppController , AppData }.
+
+handle_request(A,AppController,AppData) ->
+ handle_request(A,
+ AppController, AppController:hook(A),
+ AppData).
+
handle_request(A,
AppController,
{phased, Ewc, Func}, AppData) ->
@@ -317,7 +298,7 @@
element(1, get_initial_ewc1(Ewc)).

get_initial_ewc1({ewc, A} = Ewc) ->
- AppData = lookup_app_data_module(A),
+ AppData = erlyweb_arg:app_data(A),
get_initial_ewc1(Ewc, AppData).
get_initial_ewc1({ewc, A}, AppData) ->
case get_ewc(A, AppData) of
@@ -472,7 +453,7 @@
end.

get_ewc(A) ->
- get_ewc(A, lookup_app_data_module(A)).
+ get_ewc(A, erlyweb_arg:app_data(A)).

get_ewc(A, AppData) ->
Prefix = erlyweb_util:get_url_prefix(A),
@@ -492,7 +473,7 @@
{error, no_such_component} ->
%% if the request doesn't match a controller's name,
%% redirect it to /path
- Path = case yaws_arg:appmoddata(A) of
+ Path = case erlyweb_arg:appmoddata(A) of
[$/ | _ ] = P -> P;
Other -> [$/ | Other]
end,
@@ -508,7 +489,7 @@
%%
%% @spec get_app_name(A::arg()) -> AppName::string() | exit(Err)
get_app_name(A) ->
- case proplists:get_value("appname", yaws_arg:opaque(A)) of
+ case proplists:get_value("appname", erlyweb_arg:opaque(A)) of
undefined ->
exit({missing_appname,
"Did you forget to add the 'appname = [name]' "
@@ -523,14 +504,11 @@
%%
%% @spec get_app_root(A::arg()) -> string()
get_app_root(A) ->
- ServerPath = yaws_arg:server_path(A),
+ ServerPath = erlyweb_arg:server_path(A),
{First, _Rest} =
lists:split(
length(ServerPath) -
- length(yaws_arg:appmoddata(A)),
+ length(erlyweb_arg:appmoddata(A)),
ServerPath),
First.

-lookup_app_data_module(A) ->
- proplists:get_value(app_data_module, yaws_arg:opaque(A)).
-
Index: erlyweb_interface_yaws.erl
===================================================================
--- erlyweb_interface_yaws.erl (revision 0)
+++ erlyweb_interface_yaws.erl (revision 0)
@@ -0,0 +1,8 @@
+-module(erlyweb_interface_yaws).
+-export([out/1]).
+
+out(A) ->
+ Arg = erlyweb_arg:create(erlyweb_arg_yaws,A),
+ { Arg2 , AppController , AppData } =
erlyweb:prepare_request(Arg),
+ erlyweb:handle_request(Arg2,AppController,AppData).
+
Index: erlyweb_arg_ewgi.erl
===================================================================
--- erlyweb_arg_ewgi.erl (revision 0)
+++ erlyweb_arg_ewgi.erl (revision 0)
@@ -0,0 +1,12 @@
+-module(erlyweb_arg_ewgi).
+
+create(Env) ->
+ erlyweb_arg:create(?MODULE,Env).
+appmoddata(Env) ->
+ todo.
+server_path(Env) ->
+ todo.
+method(A) ->
+ todo.
+parse_post(A) ->
+ todo.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "erlyweb" group.
To post to this group, send email to erlyweb@googlegroups.com
To unsubscribe from this group, send email to erlyweb-unsubscribe@googlegroups.com
For more options, visit this group at http://groups.google.com/group/erlyweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Post recived from mailinglist
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum