Commits

Alvaro Videla committed b8022b9

first commit

Comments (0)

Files changed (17)

+ebin/*
+priv/log/*
+priv/logs/reports/*
+erl_crash.dump 
+% -*- mode: erlang -*-
+{["src/*"], 
+ [{i, "include"},
+  {outdir, "ebin"},
+  debug_info]
+}.
+The MIT License
+
+Copyright (c) 2009 Alvaro Videla
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+ERL          ?= erl
+EBIN_DIRS    := $(wildcard deps/*/ebin)
+APP          := trakt
+
+all: erl ebin/$(APP).app
+
+erl:
+	@$(ERL) -pa $(EBIN_DIRS) -noinput +B \
+	  -eval 'case make:all() of up_to_date -> halt(0); error -> halt(1) end.'
+
+docs:
+	@erl -noshell -run edoc_run application '$(APP)' '"."' '[]'
+
+clean: 
+	@echo "removing:"
+	@rm -fv ebin/*.beam ebin/*.app
+
+ebin/$(APP).app: src/$(APP).app
+	@cp -v src/$(APP).app $@
+/Users/alvaro/Code/webmachine/scripts/../ebin/..

priv/dispatch.conf

+{["log"], logger_resource, []}.

priv/www/index.html

+<html>
+<head>
+<title>It Worked</title>
+</head>
+<body>
+MochiWeb running.
+</body>
+</html>

src/el_logger.erl

+%% @author Alvaro Videla <alvaro@thenetcircle.com>
+%% @copyright 2009 Alvaro Videla.
+%% See LICENSE for copyright details.
+
+% Logger that uses Erlang error_logger for standard reports
+-module(el_logger).
+-author('Alvaro Videla <alvaro@thenetcircle.com>').
+
+-behaviour(gen_event).
+
+-export([init/1, handle_event/2, handle_call/2,
+         handle_info/2, terminate/2, code_change/3]).
+         
+-include("trakt.hrl").
+
+init(_Args) ->
+    {ok, []}.
+
+handle_event(Msg, State) ->
+  Priority = proplists:get_value("priority", Msg, ?ERROR),
+  report(Priority, Msg),
+  {ok, State}.
+
+terminate(_Args, _State) ->
+    ok.
+    
+handle_call(_Request, State) ->
+  {ok, ok, State}.
+
+handle_info(_Info, State) ->
+  {ok, State}.
+  
+code_change(_OldVsn, State, _Extra) ->
+  {ok, State}.
+  
+report(?ERROR, Msg) ->
+  error_logger:error_report(Msg);
+report(?INFO, Msg) ->
+  error_logger:info_report(Msg);
+report(?WARNING, Msg) ->
+  error_logger:warning_report(Msg);
+report(_Any, Msg) ->
+  error_logger:info_report(Msg).

src/logger_resource.erl

+%% @author Alvaro Videla <alvaro@thenetcircle.com>
+%% @copyright 2009 Alvaro Videla.
+%% See LICENSE for copyright details.
+
+-module(logger_resource).
+-author('Alvaro Videla <alvaro@thenetcircle.com>').
+
+-export([init/1, to_text/2, process_post/2, allowed_methods/2, content_types_provided/2]).
+
+-include_lib("webmachine/include/webmachine.hrl").
+-include("trakt.hrl").
+
+init([]) -> {ok, undefined}.
+
+allowed_methods(ReqData, State) ->
+  {['POST'], ReqData, State}.
+
+content_types_provided(ReqData, State) ->
+  {[{"text/plain", to_text}], ReqData, State}.
+
+to_text(ReqData, State) ->
+  {"OK", ReqData, State}.
+  
+process_post(ReqData, State) ->
+  case mochijson:decode(wrq:req_body(ReqData)) of
+    {struct, MJ} ->
+      gen_event:notify(?EVT_MANAGER, MJ),
+      {true, ReqData, State};
+    _ -> 
+      {false, ReqData, State}
+  end.
+{application, trakt,
+ [{description, "trakt"},
+  {vsn, "0.1"},
+  {modules, [
+    trakt,
+    trakt_app,
+    trakt_sup,
+    trakt_deps,
+    logger_resource
+  ]},
+  {registered, []},
+  {mod, {trakt_app, []}},
+  {env, []},
+  {applications, [kernel, stdlib, crypto]}]}.
+%% @author Alvaro Videla <alvaro@thenetcircle.com>
+%% @copyright 2009 Alvaro Videla.
+%% See LICENSE for copyright details.
+
+-module(trakt).
+-author('Alvaro Videla <alvaro@thenetcircle.com>').
+-export([start/0, stop/0]).
+
+ensure_started(App) ->
+    case application:start(App) of
+	ok ->
+	    ok;
+	{error, {already_started, App}} ->
+	    ok
+    end.
+	
+%% @spec start() -> ok
+%% @doc Start the trakt server.
+start() ->
+    trakt_deps:ensure(),
+    ensure_started(crypto),
+    ensure_started(webmachine),
+    application:start(trakt).
+
+%% @spec stop() -> ok
+%% @doc Stop the trakt server.
+stop() ->
+    Res = application:stop(trakt),
+    application:stop(webmachine),
+    application:stop(crypto),
+    Res.
+%% @author Alvaro Videla <alvaro@thenetcircle.com>
+%% @copyright 2009 Alvaro Videla.
+%% See LICENSE for copyright details.
+
+-define(EVT_MANAGER, {global, trakt_manager}).
+
+% Priorities
+-define (ERROR, "error").
+-define (INFO, "info").
+-define (WARNING, "warning").

src/trakt_app.erl

+%% @author Alvaro Videla <alvaro@thenetcircle.com>
+%% @copyright 2009 Alvaro Videla.
+%% See LICENSE for copyright details.
+
+%% @doc Callbacks for the trakt application.
+
+-module(trakt_app).
+-author('Alvaro Videla <alvaro@thenetcircle.com>').
+
+-behaviour(application).
+-export([start/2,stop/1]).
+
+
+%% @spec start(_Type, _StartArgs) -> ServerRet
+%% @doc application start callback for trakt.
+start(_Type, _StartArgs) ->
+    trakt_deps:ensure(),
+    trakt_sup:start_link().
+
+%% @spec stop(_State) -> ServerRet
+%% @doc application stop callback for trakt.
+stop(_State) ->
+    ok.

src/trakt_deps.erl

+%% @author Alvaro Videla <alvaro@thenetcircle.com>
+%% @copyright 2009 Alvaro Videla.
+%% See LICENSE for copyright details.
+
+%% @doc Ensure that the relatively-installed dependencies are on the code
+%%      loading path, and locate resources relative
+%%      to this application's path.
+
+-module(trakt_deps).
+-author('Alvaro Videla <alvaro@thenetcircle.com>').
+
+-export([ensure/0, ensure/1]).
+-export([get_base_dir/0, get_base_dir/1]).
+-export([local_path/1, local_path/2]).
+-export([deps_on_path/0, new_siblings/1]).
+
+%% @spec deps_on_path() -> [ProjNameAndVers]
+%% @doc List of project dependencies on the path.
+deps_on_path() ->
+    F = fun (X, Acc) ->
+                ProjDir = filename:dirname(X),
+                case {filename:basename(X),
+                      filename:basename(filename:dirname(ProjDir))} of
+                    {"ebin", "deps"} ->
+                        [filename:basename(ProjDir) | Acc];
+                    _ ->
+                        Acc
+                end
+        end,
+    ordsets:from_list(lists:foldl(F, [], code:get_path())).
+    
+%% @spec new_siblings(Module) -> [Dir]
+%% @doc Find new siblings paths relative to Module that aren't already on the
+%%      code path.
+new_siblings(Module) ->
+    Existing = deps_on_path(),
+    SiblingEbin = filelib:wildcard(local_path(["deps", "*", "ebin"], Module)),
+    Siblings = [filename:dirname(X) || X <- SiblingEbin,
+                           ordsets:is_element(
+                             filename:basename(filename:dirname(X)),
+                             Existing) =:= false],
+    lists:filter(fun filelib:is_dir/1, 
+                 lists:append([[filename:join([X, "ebin"]),
+                                filename:join([X, "include"])] ||
+                                  X <- Siblings])).
+        
+
+%% @spec ensure(Module) -> ok
+%% @doc Ensure that all ebin and include paths for dependencies
+%%      of the application for Module are on the code path.
+ensure(Module) ->
+    code:add_paths(new_siblings(Module)),
+    code:clash(),
+    ok.
+
+%% @spec ensure() -> ok
+%% @doc Ensure that the ebin and include paths for dependencies of
+%%      this application are on the code path. Equivalent to
+%%      ensure(?Module).
+ensure() ->
+    ensure(?MODULE).
+
+%% @spec get_base_dir(Module) -> string()
+%% @doc Return the application directory for Module. It assumes Module is in
+%%      a standard OTP layout application in the ebin or src directory.
+get_base_dir(Module) ->
+    {file, Here} = code:is_loaded(Module),
+    filename:dirname(filename:dirname(Here)).
+
+%% @spec get_base_dir() -> string()
+%% @doc Return the application directory for this application. Equivalent to
+%%      get_base_dir(?MODULE).
+get_base_dir() ->
+    get_base_dir(?MODULE).
+
+%% @spec local_path([string()], Module) -> string()
+%% @doc Return an application-relative directory from Module's application.
+local_path(Components, Module) ->
+    filename:join([get_base_dir(Module) | Components]).
+
+%% @spec local_path(Components) -> string()
+%% @doc Return an application-relative directory for this application.
+%%      Equivalent to local_path(Components, ?MODULE).
+local_path(Components) ->
+    local_path(Components, ?MODULE).

src/trakt_sup.erl

+%% @author Alvaro Videla <alvaro@thenetcircle.com>
+%% @copyright 2009 Alvaro Videla.
+%% See LICENSE for copyright details.
+
+%% @doc Supervisor for the trakt application.
+
+-module(trakt_sup).
+-author('Alvaro Videla <alvaro@thenetcircle.com>').
+
+-behaviour(supervisor).
+
+%% External exports
+-export([start_link/0, upgrade/0]).
+
+%% supervisor callbacks
+-export([init/1]).
+
+-include("trakt.hrl").
+
+%% @spec start_link() -> ServerRet
+%% @doc API for starting the supervisor.
+start_link() ->
+    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+%% @spec upgrade() -> ok
+%% @doc Add processes if necessary.
+upgrade() ->
+    {ok, {_, Specs}} = init([]),
+
+    Old = sets:from_list(
+      [Name || {Name, _, _, _} <- supervisor:which_children(?MODULE)]),
+    New = sets:from_list([Name || {Name, _, _, _, _, _} <- Specs]),
+    Kill = sets:subtract(Old, New),
+
+    sets:fold(fun (Id, ok) ->
+          supervisor:terminate_child(?MODULE, Id),
+          supervisor:delete_child(?MODULE, Id),
+          ok
+        end, ok, Kill),
+
+    [supervisor:start_child(?MODULE, Spec) || Spec <- Specs],
+    ok.
+
+%% @spec init([]) -> SupervisorTree
+%% @doc supervisor callback.
+init([]) ->
+    Ip = case os:getenv("WEBMACHINE_IP") of false -> "0.0.0.0"; Any -> Any end,
+    {ok, Dispatch} = file:consult(filename:join(
+                         [filename:dirname(code:which(?MODULE)),
+                          "..", "priv", "dispatch.conf"])),
+    WebConfig = [
+     {ip, Ip},
+     {port, 8000},
+                 {log_dir, "priv/log"},
+     {dispatch, Dispatch}],
+    Web = {webmachine_mochiweb,
+     {webmachine_mochiweb, start, [WebConfig]},
+     permanent, 5000, worker, dynamic},
+     
+    EvtManager = {trakt,
+    {gen_event, start_link, [?EVT_MANAGER]},
+    permanent, 5000, worker, dynamic},
+     
+    Processes = [Web, EvtManager],
+    {ok, {{one_for_one, 10, 10}, Processes}}.
+#!/bin/sh
+cd `dirname $0`
+exec erl -pa $PWD/ebin $PWD/deps/*/ebin $PWD/deps/*/deps/*/ebin \
+-boot start_sasl -config ./priv/logger \
+-s reloader -s trakt -name trakt
+#-detached
+#!/bin/sh
+cd `dirname $0`
+exec erl -pa $PWD/ebin $PWD/deps/*/ebin $PWD/deps/*/deps/*/ebin -boot start_sasl -s trakt