Skip to content

Commit e7d7ddc

Browse files
author
Raoul Hess
committed
WIP making right calls depending on stage or production.
1 parent 3d374b9 commit e7d7ddc

File tree

8 files changed

+157
-107
lines changed

8 files changed

+157
-107
lines changed

Makefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
PROJECT = divapi
22

3-
DEPS = cowboy jiffy libsass sassc raven
3+
DEPS = cowboy jiffy libsass sassc raven lager
44
dep_libsass = git https://github.com/sass/libsass.git master
55
dep_sassc = git https://github.com/sass/sassc.git master
6+
dep_lager = git https://github.com/basho/lager.git master
67
dep_raven = git https://github.com/soundrop/raven-erlang.git master
78

89
TEST_DEPS = meck
910
dep_meck = git https://github.com/eproxus/meck.git master
1011

1112
export SASS_LIBSASS_PATH = $(DEPS_DIR)/libsass
1213

14+
include erlang.mk
15+
16+
ERLC_COMPILE_OPTS= +'{parse_transform, lager_transform}'
17+
18+
ERLC_OPTS += $(ERLC_COMPILE_OPTS)
19+
TEST_ERLC_OPTS += $(ERLC_COMPILE_OPTS)
20+
1321
all:: deps priv/
1422
cp $(DEPS_DIR)/sassc/bin/sassc priv/
1523

1624
priv/:
1725
mkdir priv
18-
19-
include erlang.mk

log.config

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[
2+
{lager, [
3+
{handlers, [
4+
{lager_console_backend, info},
5+
{lager_file_backend, [{file, "log/error.log"}, {level, error}, {size, 20971520}, {count, 10}]},
6+
{lager_file_backend, [{file, "log/info.log"}, {level, info}, {size, 20971520}, {count, 10}]}
7+
]}
8+
]}
9+
].

rel/sys.config

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
[{
2-
divapi, [{repo_dir, ""}, %% Path to your directory
2+
divapi, [{repo_dir, <<"/Users/roh/Dev/tmp/components2">>}, %% Path to your directory
33
{nodes, []},
4-
{component_cache, ""},
5-
{port, 8181}] %% Port to run the server on
4+
{component_cache, <<"/Users/roh/Dev/tmp/js_minified/">>},
5+
{port, 8181},
6+
{stage, [
7+
{fallback, <<"api.diversity.io">>}
8+
]}]
69
}].

src/component_handler.erl

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,39 +27,72 @@ handle(Req, State=#state{}) ->
2727
%% @doc Handle a GET-request
2828
handle_get(Req, _State=#state{}) ->
2929
{ComponentName, Req1} = cowboy_req:binding(component, Req),
30-
case component_exists(ComponentName) of
31-
true ->
32-
handle_component_request(Req1, ComponentName);
33-
false ->
34-
reply_from_result_data(Req1, resource_not_found)
30+
case application:get_env(divapi, stage) of
31+
undefined ->
32+
case divapi_component:exists(ComponentName) of
33+
true ->
34+
handle_component_request(Req1, divapi_component:dir(ComponentName));
35+
false ->
36+
reply_from_result_data(Req1, resource_not_found)
37+
end;
38+
{ok, StageEnv} ->
39+
%% Get the subdomain for staging env as key for checking component.
40+
{Host, Req2} = cowboy_req:host(Req1),
41+
[Stage, _] = binary:split(Host, <<".">>),
42+
case divapi_component:exists(ComponentName, Stage) of
43+
true ->
44+
lager:info("Local request"),
45+
handle_component_request(Req2, divapi_component:dir(ComponentName, Stage));
46+
false ->
47+
%% Do a fallback call!!
48+
FallBackUrl = proplists:get_value(fallback, StageEnv),
49+
Opts = [{body_format, binary}],
50+
{Path, Req3} = cowboy_req:path(Req2),
51+
{Qs, Req4} = cowboy_req:qs(Req3),
52+
Url = <<"http://", FallBackUrl/binary, Path/binary, "?", Qs/binary>>,
53+
Request = {unicode:characters_to_list(Url), []},
54+
Result = case httpc:request(get, Request, [], Opts) of
55+
{ok, {{_Version, Status, _ReasonPhrase}, Headers, Body}} ->
56+
case Status of
57+
404 -> resource_not_found;
58+
500 -> {error, <<"Failed to fetch from fallback">>};
59+
200 -> {ok, Body, Headers}
60+
end
61+
end,
62+
case Result of
63+
{ok, ReplyBody, ReplyHeaders} ->
64+
lager:info("~p", [ReplyHeaders]),
65+
ContentType = proplists:get_value("content-type", ReplyHeaders),
66+
cowboy_req:reply(200, [{<<"content-type">>, unicode:characters_to_binary(ContentType)}] ++ ?ACCESS_CONTROL_HEADER, ReplyBody, Req);
67+
% cowboy_req:reply(200, ReplyBody, Req);
68+
_ ->
69+
reply_from_result_data(Req4, Result)
70+
end
71+
end
3572
end.
3673

37-
%% @doc Check if a component is exists in the repository directory
38-
component_exists(ComponentName) ->
39-
{ok, RepoDir} = application:get_env(divapi, repo_dir),
40-
filelib:is_dir(RepoDir ++ "/" ++ binary_to_list(ComponentName) ++ ".git").
41-
4274
%% @doc Handle a component-request
4375
%% The possible routes to this function is:
4476
%% /ComponentName/ - List all tags
4577
%% /ComponentName/Tag/ - Serve diversity.json
4678
%% /ComponentName/Tag/files/some.file - Serve a file
4779
%% /ComponentName/Tag/css - Serve concatenated CSS
4880
%% /ComponentName/Tag/thumbnail - Serve thumbnail
49-
handle_component_request(Req, ComponentName) ->
81+
handle_component_request(Req, ComponentPath) ->
5082
{PathInfo, Req1} = cowboy_req:path_info(Req),
5183
ResultData = case PathInfo of
5284
undefined ->
53-
{json, jiffy:encode(divapi_component:tags(ComponentName))};
85+
{json, jiffy:encode(divapi_component:tags(ComponentPath))};
5486
[PartialTag | Routes] ->
5587
%% Try to expand the tag into an existing one
56-
try expand_tag(PartialTag, divapi_component:tags(ComponentName)) of
88+
try expand_tag(PartialTag, divapi_component:tags(ComponentPath)) of
5789
Tag ->
90+
lager:info("~p", [Tag]),
5891
case Routes of
5992
[] ->
60-
{json, divapi_component:diversity_json(ComponentName, Tag)};
93+
{json, divapi_component:diversity_json(ComponentPath, Tag)};
6194
[Settings] when Settings =:= <<"settings">> ->
62-
{json, divapi_component:settings(ComponentName, Tag)};
95+
{json, divapi_component:settings(ComponentPath, Tag)};
6396
[Settings] when Settings =:= <<"settingsForm">> ->
6497
{json, divapi_component:settingsform(Tag, Settings)};
6598
[<<"files">> | Path] ->
@@ -81,7 +114,7 @@ handle_component_request(Req, ComponentName) ->
81114
Headers ++ [{<<"Cache-Control">>, <<"max-age=90000">>},
82115
{<<"Etag">>, <<Tag/binary, File/binary>>}]
83116
end,
84-
case divapi_component:file(ComponentName, Tag, File) of
117+
case divapi_component:file(ComponentPath, Tag, File) of
85118
FileBin when is_binary(FileBin) ->
86119
{ok, {Headers1, FileBin}};
87120
FileFailure ->
@@ -92,13 +125,13 @@ handle_component_request(Req, ComponentName) ->
92125
%% Retrive additional variables and sort them to get a
93126
%% consistent cache key
94127
{Variables, _Req2} = cowboy_req:qs_vals(Req1),
95-
{css, divapi_component:css(ComponentName, Tag, Variables)};
128+
{css, divapi_component:css(ComponentPath, Tag, Variables)};
96129
[<<"thumbnail">>] ->
97130
{BrowserEtag, _} = cowboy_req:header(<<"if-none-match">>, Req1),
98-
Etag = <<"*", ComponentName/binary>>,
131+
Etag = <<"css*", ComponentPath/binary>>,
99132
case BrowserEtag of
100133
Etag -> file_not_changed;
101-
_ -> divapi_component:thumbnail(ComponentName)
134+
_ -> divapi_component:thumbnail(ComponentPath)
102135
end;
103136
_ ->
104137
resource_not_found
@@ -126,8 +159,6 @@ reply_from_result_data(Req, {json, Data}) ->
126159
reply_from_result_data(Req, {css, Data}) ->
127160
cowboy_req:reply(200, ?ACCESS_CONTROL_HEADER ++ ?CSS_HEADER, Data, Req).
128161

129-
130-
131162
%% @doc Expand an incoming tag into the latest matching tag
132163
%% Supported formats are:
133164
%% * - Latest version

src/divapi.app.src

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
jiffy,
1111
raven,
1212
ssl,
13+
lager,
1314
cowboy
1415
]},
1516
{mod, {divapi_app, []}},

src/divapi_cache.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ get(Key, Fun, Timeout) ->
2929
%% The file does not exist in the cache
3030
[] ->
3131
Value = Fun(),
32-
case divapi:is_prod() of
32+
case divapi_app:is_production() of
3333
true ->
3434
Value;
3535
false ->

src/divapi_component.erl

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
-module(divapi_component).
22

3-
-export([tags/1, diversity_json/2, settings/2, settingsForm/2, file/3, css/3, thumbnail/1]).
3+
-export([tags/1, diversity_json/2, settings/2, settingsForm/2, file/3, css/3, thumbnail/1,
4+
dir/1, dir/2, exists/1, exists/2]).
45

56
%% @doc Retrive all tags for a given component
6-
tags(ComponentName) ->
7-
git_utils:tags(ComponentName).
7+
tags(ComponentPath) ->
8+
git_utils:tags(ComponentPath).
89

910
%% @doc Fetches the diversity json for a spcific component/tag. Will cache the result.
10-
diversity_json(ComponentName, Tag) ->
11+
diversity_json(ComponentPath, Tag) ->
1112
divapi_cache:get(
12-
{diversity_json, ComponentName, Tag},
13-
fun () -> jiffy:decode(git_utils:get_diversity_json(ComponentName, Tag)) end,
13+
{diversity_json, ComponentPath, Tag},
14+
fun () -> jiffy:decode(file(ComponentPath, Tag,<<"diversity.json">>)) end,
1415
1000 * 60 * 60 * 5 % 5 hours
1516
).
1617

1718
%% @doc Serve the settings from diversity.json
18-
settings(ComponentName, Tag) ->
19-
case diversity_json(ComponentName, Tag) of
19+
settings(ComponentPath, Tag) ->
20+
case diversity_json(ComponentPath, Tag) of
2021
undefined ->
2122
resource_not_found;
2223
Json ->
@@ -27,8 +28,8 @@ settings(ComponentName, Tag) ->
2728
end.
2829

2930
%% @doc Serve the settingsForm from diversity.json
30-
settingsForm(ComponentName, Tag) ->
31-
case diversity_json(ComponentName, Tag) of
31+
settingsForm(ComponentPath, Tag) ->
32+
case diversity_json(ComponentPath, Tag) of
3233
undefined ->
3334
resource_not_found;
3435
Json ->
@@ -38,26 +39,34 @@ settingsForm(ComponentName, Tag) ->
3839
SettingsJson
3940
end.
4041

41-
42-
%% @doc Serve an arbitrary file from the repository
43-
44-
file(ComponentName, Tag, File) ->
45-
case git_utils:get_file(ComponentName, Tag, File) of
46-
undefined ->
47-
resource_not_found;
48-
error ->
49-
%% Should get a reason from git_utils get_file command.
50-
{error, <<"Error while fetching file">>};
51-
FileBin ->
52-
FileBin
42+
%% @doc Serve an arbitrary file for the component
43+
file(ComponentPath, Tag, File) ->
44+
case divapi_app:is_production() of
45+
true ->
46+
%% Read the file!!
47+
Path = filename:join(ComponentPath, File),
48+
case file:read(Path) of
49+
{ok, FileBin} -> FileBin;
50+
_ -> resource_not_found
51+
end;
52+
false ->
53+
case git_utils:get_file(ComponentPath, Tag, File) of
54+
undefined ->
55+
resource_not_found;
56+
error ->
57+
%% Should get a reason from git_utils get_file command.
58+
{error, <<"Error while fetching file">>};
59+
FileBin ->
60+
FileBin
61+
end
5362
end.
5463

5564
%% @doc Serve all css and sass (concatenated into one file)
5665
%% This function will check out the diversity.json-file from the components repository
5766
%% and check the styles-property to find all the css- and sass-files. The sass files are
5867
%% first compiled then all css is concatenated and returned to the user.
59-
css(ComponentName, Tag, Variables0) ->
60-
case git_utils:get_diversity_json(ComponentName, Tag) of
68+
css(ComponentPath, Tag, Variables0) ->
69+
case git_utils:get_diversity_json(ComponentPath, Tag) of
6170
undefined ->
6271
resource_not_found;
6372
DiversityData ->
@@ -72,42 +81,64 @@ css(ComponentName, Tag, Variables0) ->
7281
%% To get a consitent cache key we need to make sure the proplist is sorted
7382
Variables1 = lists:sort(Variables0),
7483
Files = divapi_cache:get(
75-
{css, ComponentName, Tag, Variables1},
76-
fun () -> get_css(ComponentName, Tag, Variables1, StylePaths) end,
84+
{css, ComponentPath, Tag, Variables1},
85+
fun () -> get_css(ComponentPath, Tag, Variables1, StylePaths) end,
7786
1000 * 60 * 60 * 5 % 5 hours
7887
),
7988
{css, Files}
8089
end.
8190

82-
thumbnail(ComponentName) ->
83-
case git_utils:get_diversity_json(ComponentName, <<"*">>) of
91+
thumbnail(ComponentPath) ->
92+
case git_utils:get_diversity_json(ComponentPath, <<"*">>) of
8493
undefined ->
8594
resource_not_found;
8695
Json ->
8796
{DiversityData} = jiffy:decode(Json),
8897
ThumbnailPath = proplists:get_value(<<"thumbnail">>, DiversityData, undefined),
89-
file(ComponentName, <<"*">>, ThumbnailPath)
98+
file(ComponentPath, <<"*">>, ThumbnailPath)
9099
end.
91100

92101
%% @doc Retrive al
93-
get_css(ComponentName, Tag, Variables, Paths) ->
102+
get_css(ComponentPath, Tag, Variables, Paths) ->
94103
%% Retrive all files(CSS and SCSS).
95104
%% Compile all SCSS-files to CSS and then concatenate all of them
96105
GetFile = fun (Path) ->
97106
%% Retrive the temporary checked out file from the repository
98-
File = git_utils:get_file(ComponentName, Tag, Path),
107+
File = file(ComponentPath, Tag, Path),
99108
case filename:extension(Path) of
100109
<<".scss">> ->
101-
sass_compile(ComponentName, Tag, Path, File, Variables);
110+
sass_compile(ComponentPath, Tag, Path, File, Variables);
102111
<<".css">> ->
103112
File
104113
end
105114
end,
106115
lists:map(GetFile, Paths).
107116

117+
dir(ComponentPath) ->
118+
{ok, RepoDir} = application:get_env(divapi, repo_dir),
119+
RepoDir1 = case is_binary(RepoDir) of
120+
true -> RepoDir;
121+
false -> unicode:character_to_binary(RepoDir)
122+
end,
123+
<<RepoDir1/binary, "/", ComponentPath/binary, ".git">>.
124+
125+
dir(ComponentPath, Stage) ->
126+
{ok, RepoDir} = application:get_env(divapi, repo_dir),
127+
RepoDir1 = case is_binary(RepoDir) of
128+
true -> RepoDir;
129+
false -> unicode:character_to_binary(RepoDir)
130+
end,
131+
<<RepoDir1/binary, "/", Stage/binary, "/", ComponentPath/binary, ".git">>.
132+
133+
exists(ComponentPath) ->
134+
filelib:is_dir(dir(ComponentPath)).
135+
136+
exists(ComponentPath, Stage) ->
137+
lager:info("Eeeeeh... ~p", [dir(ComponentPath, Stage)]),
138+
filelib:is_dir(dir(ComponentPath, Stage)).
108139

109140
%% @doc Compile a sass-file with given variables
110-
sass_compile(ComponentName, Tag, Path, File, Variables) ->
141+
sass_compile(ComponentPath, Tag, Path, File, Variables) ->
111142

112143
%% Construct the SASS-variables
113144
VarToBinary = fun ({Variable, Value}, BinAcc) ->
@@ -117,7 +148,7 @@ sass_compile(ComponentName, Tag, Path, File, Variables) ->
117148
BinaryVars = lists:foldl(VarToBinary, <<>>, Variables),
118149

119150
%% Create a temporary sass file
120-
TmpName0 = {ComponentName, Tag, Path, Variables},
151+
TmpName0 = {ComponentPath, Tag, Path, Variables},
121152
TmpName1 = integer_to_binary(erlang:phash2(TmpName0)),
122153
TmpPath = filename:join(<<"/tmp/divapi/">>, TmpName1),
123154
ok = filelib:ensure_dir(TmpPath),

0 commit comments

Comments
 (0)