Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

move JS code out of -defines and into .js files

greatly improves readability

JS files are read during application startup, and storing in
the application environment under properties named after their filenames
  • Loading branch information...
commit 94c90589dfff8953a3fecaa134143c6f06e15339 1 parent b9be0e0
Bryan Fink beerriot authored
51 apps/wriaki/priv/mapred/search_map.js
View
@@ -0,0 +1,51 @@
+// This function is used as the map phase implementation for
+// searching article text
+// Each element in the result should be a structure of
+// {
+// key: (string), // key of the Riak object for the article
+// ranges: [ (string) ], // list of matching phrases
+// }
+function(v, d) {
+ // always want the key in the result
+ var result = {key: v.key};
+
+ // if the object was found, and we have word position info
+ if (v.values && v.values[0] && d.p) {
+ // sort positions
+ d.p.sort();
+
+ // create a list of start/end position pairs that attempt
+ // to group "close" positions (within 5 words) together
+ result.ranges=[{start: d.p[0], end: d.p[0]}];
+ for (var i = 1; i < d.p.length; i++) {
+ if (result.ranges[result.ranges.length-1].end-d.p[i] < 5)
+ result.ranges[result.ranges.length-1].end = d.p[i];
+ else
+ result.ranges[result.ranges.length] =
+ {start: d.p[i], end: d.p[i]};
+ }
+
+ // extract the phrases from the text
+ var text = JSON.parse(v.values[0].data).text;
+ var words = text.match(/[a-z0-9\u80-\uff]*/g).filter(
+ function(s) { return s != ""; }).length
+
+ for (var i = 0; i < result.ranges.length; i++) {
+ var s = result.ranges[i].start < 5 ?
+ 0 : result.ranges[i].start-5;
+ var e = result.ranges[i].end+5 > words ?
+ words : result.ranges[i].end+5;
+
+ // regexp is basically "match START words, then grab everything
+ // until WORDS-END words from the end"
+ var match = (new RegExp(
+ "(?:[a-z0-9\u80-\uff]+[^a-z0-9\u80-\uff]+){"+s+"}"+
+ "(.*)[^a-z0-9\u80-\uff]"+
+ "(?:[a-z0-9\u80-\uff]+[^a-z0-9\u80-\uff]+){"+(words-e)+"}"))
+ .exec(text);
+ result.ranges[i] = match[1];
+ }
+ }
+
+ return [result];
+}
24 apps/wriaki/priv/mapred/summary_map.js
View
@@ -0,0 +1,24 @@
+// This function is used as the map phase implementation for
+// extracting summary data from archives for history production
+// Each element in the result should be a structure of
+// {
+// version: (string), // the hash version of the revision
+// timestamp: (integer), // the time of the revision
+// message: (string), // the commit message
+// editor: (string), // the username of the editor
+// }
+function(v) {
+ var json = JSON.parse(v.values[0].data);
+ var summary = {
+ version: json.version,
+ timestamp: json.timestamp,
+ message: json.message,
+ };
+ var links = v.values[0].metadata.Links;
+ for(var i in links) {
+ if (links[i][2] == "editor") {
+ summary.editor = links[i][1];
+ }
+ }
+ return [summary];
+}
7 apps/wriaki/priv/mapred/time_order_reduce.js
View
@@ -0,0 +1,7 @@
+// This function is used as the reduce phase implementation for
+// ordering/paging archives in the history view (TODO)
+function(v) {
+ return v.sort(
+ function(a,b) { return b[2]-a[2]; }
+ );
+}
39 apps/wriaki/src/article_history.erl
View
@@ -60,37 +60,22 @@ merge_links(Obj, Acc) ->
Acc,
wobj:get_links(Obj)).
--define(TIME_ORDER,
- iolist_to_binary(
- [<<"function(v) {\n">>,
- <<"return v.sort(\n">>,
- <<"function(a,b) { return b[2]-a[2]; }\n">>,
- <<"); }">>])).
-
--define(SUMMARY_EXTRACTION,
- iolist_to_binary(
- [<<"function(v) {\n">>,
- <<"var json = JSON.parse(v.values[0].data);\n">>,
- <<"var summary = {\n">>,
- <<"version: json.version,\n">>,
- <<"timestamp: json.timestamp,\n">>,
- <<"message: json.message,\n">>,
- <<"};\n">>,
- <<"var links = v.values[0].metadata.Links;\n">>,
- <<"for(var i in links) {\n">>,
- <<"if (links[i][2] == \"editor\") {\n">>,
- <<"summary.editor = links[i][1];\n">>,
- <<"}\n">>,
- <<"}\n">>,
- <<"return [summary];\n">>,
- <<"}">>])).
-
get_version_summaries(ArticleKey) ->
{ok, Client} = wrc:connect(),
{ok, [{1, Results}]} =
wrc:mapred(Client,
[{?B_HISTORY, ArticleKey}],
[{link, <<"archive">>, '_', false},
-%%%{reduce, {jsanon, ?TIME_ORDER}, <<>>, false}, %TODO: paging
- {map, {jsanon, ?SUMMARY_EXTRACTION}, <<>>, true}]),
+%%%{reduce, {jsanon, time_order_fun()}, <<>>, false}, %TODO: paging
+ {map, {jsanon, summary_fun()}, <<>>, true}]),
{ok, Results}.
+
+%% code for summary map phase is in priv/mapred/summary_map.js
+summary_fun() ->
+ wriaki:get_app_env(summary_map,
+ <<"function() { return []; }">>).
+
+%% code for time order reduce phase is in priv/mapred/time_order_reduce.js
+time_order_fun() ->
+ wriaki:get_app_env(time_order_reduce,
+ <<"function(v) { return v; }">>).
48 apps/wriaki/src/wiki_resource.erl
View
@@ -253,47 +253,6 @@ render_404(RD, Ctx) ->
{results, Results}]),
{C, RD, Ctx}.
--define(SEARCH_FUN,
- iolist_to_binary(
- [<<"function(v, d) {\n">>,
-
- %% always want the key in the result
- <<"var result = {key: v.key};\n">>,
-
- %% if the object was found, and we have word position info
- <<"if (v.values && v.values[0] && d.p) {\n">>,
-
- %% sort positions
- <<"d.p.sort();\n">>,
-
- %% create a list of start/end position pairs that attempt
- %% to group "close" positions (within 5 words) together
- <<"result.ranges=[{start: d.p[0], end: d.p[0]}];\n">>,
- <<"for (var i = 1; i < d.p.length; i++) {\n">>,
- <<"if (result.ranges[result.ranges.length-1].end-d.p[i] < 5)\n">>,
- <<"result.ranges[result.ranges.length-1].end = d.p[i];\n">>,
- <<"else\n">>,
- <<"result.ranges[result.ranges.length] = {start: d.p[i], end: d.p[i]};\n">>,
- <<"}\n">>,
-
- %% extract the phrases from the text
- <<"var text = JSON.parse(v.values[0].data).text;\n">>,
- <<"var words = text.match(/[a-z0-9\u80-\uff]*/g).filter(function(s) { return s != \"\"; }).length\n">>,
-
- <<"for (var i = 0; i < result.ranges.length; i++) {\n">>,
- <<"var s = result.ranges[i].start < 5 ? 0 : result.ranges[i].start-5;\n">>,
- <<"var e = result.ranges[i].end+5 > words ? words : result.ranges[i].end+5;\n">>,
- %% regexp is basically "match START words, then grab everything
- %% until WORDS-END words from the end"
- <<"var match = (new RegExp(\"(?:[a-z0-9\u80-\uff]+[^a-z0-9\u80-\uff]+){\"+s+\"}(.*)[^a-z0-9\u80-\uff](?:[a-z0-9\u80-\uff]+[^a-z0-9\u80-\uff]+){\"+(words-e)+\"}\")).exec(text);\n">>,
- <<"result.ranges[i] = match[1];\n">>,
- <<"}\n">>,
-
- <<"}\n">>, % end of if values & positions
-
- <<"return [result];\n">>,
- <<"}">>])).
-
search(Client, RawSearch) ->
case wriaki:search_enabled() of
true ->
@@ -302,7 +261,7 @@ search(Client, RawSearch) ->
wrc:mapred(Client,
{modfun, riak_search, mapred_search,
[<<"article">>, iolist_to_binary(Search)]},
- [{map, {jsanon, ?SEARCH_FUN}, <<>>, true}]),
+ [{map, {jsanon, search_fun()}, <<>>, true}]),
case RawResults of
[{0, Results}] ->
[ [{title, base64url:decode(
@@ -316,6 +275,11 @@ search(Client, RawSearch) ->
[]
end.
+%% code for search map phase is in priv/mapred/search_map.js
+search_fun() ->
+ wriaki:get_app_env(search_map,
+ <<"function(v) { return [{key:v.key}]; }">>).
+
split_search(Search) ->
Tokens = string:tokens(Search, " "),
string:join([ [<<"text:">>, T] || T <- Tokens ], " OR ").
14 apps/wriaki/src/wriaki.erl
View
@@ -21,6 +21,7 @@
-export([set_bucket_props/0,
search_enabled/0,
+ read_mapred_js/0,
get_app_env/2]).
-include_lib("wriaki.hrl").
@@ -48,3 +49,16 @@ get_app_env(Env, Default) ->
{ok, Val} -> Val;
undefined -> Default
end.
+
+%% Read each file in PRIV/mapred/<filename>.js and set its content
+%% as wriaki application env <filename>
+read_mapred_js() ->
+ Dir = filename:join(code:priv_dir(wriaki), "mapred"),
+ Filenames = filelib:wildcard("*.js", Dir),
+ lists:foreach(
+ fun(Name) ->
+ {ok, Content} = file:read_file(filename:join(Dir, Name)),
+ Atom = list_to_atom(hd(string:tokens(Name, "."))),
+ application:set_env(wriaki, Atom, Content)
+ end,
+ Filenames).
1  apps/wriaki/src/wriaki_sup.erl
View
@@ -45,6 +45,7 @@ start_link() ->
init([]) ->
wriaki:set_bucket_props(),
+ wriaki:read_mapred_js(),
Ip = wriaki:get_app_env(web_ip, "0.0.0.0"),
Port = wriaki:get_app_env(web_port, 8000),
Please sign in to comment.
Something went wrong with that request. Please try again.