1. orbitz
  2. iderlone

Commits

orbitz  committed 876d575

Minimal working support for evaluating things on ideone

  • Participants
  • Parent commits 6c01373
  • Branches default

Comments (0)

Files changed (3)

File src/ide1_dirt.erl

View file
 %%%-------------------------------------------------------------------
 -module(ide1_dirt).
 
+-include_lib("xmerl/include/xmerl.hrl").
+
 -define(WSDL_URL, "http://ideone.com/api/1/service.wsdl").
 -define(SERVICES_URL, "http://ideone.com/api/1/service").
 
+-define(MAP_TYPE, "ns2:Map").
+-define(INT_TYPE, "xsd:int").
+-define(STRING_TYPE, "xsd:string").
+-define(FLOAT_TYPE, "xsd:float").
+-define(BOOLEAN_TYPE, "xsd:boolean").
+
 %% API
 -export([call/2]).
 
                                                    [{"SOAPAction", Url}],
                                                    post,
                                                    Request),
-    {ok, Body}.
+    extract(Body).
     
 
+extract(String) ->
+    {Xml, _} = xmerl_scan:string(String),
+    #xmlElement{content=[Envelope]} = Xml,
+    #xmlElement{content=[Body]} = Envelope,
+    #xmlElement{content=[Return]} = Body,
+    #xmlElement{content=Top_level_map, attributes=[#xmlAttribute{value=?MAP_TYPE}]} = Return,
+    xml_map_to_list(Top_level_map).
+
+xml_map_to_list([]) ->
+    [];
+xml_map_to_list([#xmlElement{name=item, content=[Key_xml, Value_xml]} | Rest]) ->
+    #xmlElement{name=key, content=[#xmlText{value=Key}]} = Key_xml,
+    #xmlElement{name=value, content=Value, attributes=Attributes} = Value_xml,
+    Parsed_value = case lists:keyfind('xsi:type', 2, Attributes) of
+                       false ->
+                           error;
+                       #xmlAttribute{value=?MAP_TYPE} ->
+                           xml_map_to_list(Value);
+                       #xmlAttribute{value=?STRING_TYPE} ->
+                           case Value of
+                               [Value_text] ->
+                                   Value_text#xmlText.value;
+                               [] ->
+                                   ""
+                           end;
+                       #xmlAttribute{value=?INT_TYPE} ->
+                           [Value_text] = Value,
+                           list_to_integer(Value_text#xmlText.value);
+                       #xmlAttribute{value=?FLOAT_TYPE} ->
+                           [Value_text] = Value,
+                           convert_float(Value_text#xmlText.value);
+                       #xmlAttribute{value=?BOOLEAN_TYPE} ->
+                           [Value_text] = Value,
+                           list_to_atom(Value_text#xmlText.value)
+                   end,
+    [{Key, Parsed_value} | xml_map_to_list(Rest)].
+
+
 %%%===================================================================
 %%% Internal functions
 %%%===================================================================
         arguments(Index + 1, Rest).
 
                         
+convert_float(Str) ->
+    try list_to_float(Str) of
+        Float ->
+             Float
+    catch
+        _:_ ->
+            list_to_integer(Str)
+    end.

File src/ide1_evaluate.erl

View file
+%%%-------------------------------------------------------------------
+%%% @author orbitz <orbitz@osx.local>
+%%% @copyright (C) 2011, orbitz
+%%% @doc
+%%% API for working with ideone
+%%% @end
+%%% Created : 18 Oct 2011 by orbitz <orbitz@osx.local>
+%%%-------------------------------------------------------------------
+-module(ide1_evaluate).
+
+-record(account, {user, pass, language_list}).
+
+%% API
+-export([create_account/2,
+         submit/6,
+         get_submission_status/2,
+         get_submission_details/2,
+         evaluate/3,
+         get_language/2]).
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+%%--------------------------------------------------------------------
+%% @doc
+%% @spec
+%% @end
+%%--------------------------------------------------------------------
+create_account(User, Pass) ->
+    Language_list = ide1_dirt:call("getLanguages", [{"xsd:string", User}, {"xsd:string", Pass}]),
+    {"languages", Languages} = lists:keyfind("languages", 1, Language_list),
+    #account{user=User,
+             pass=Pass,
+             language_list=Languages}.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% @spec
+%% @end
+%%--------------------------------------------------------------------
+get_language(Account, Language_name) when is_list(Language_name) ->
+    case lists:keyfind(Language_name, 2, Account#account.language_list) of
+        {Id, Language_name} ->
+            {ok, Id};
+        false ->
+            {error, language_not_found}
+    end.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% @spec
+%% @end
+%%--------------------------------------------------------------------
+submit(Account, Sourcecode, Language_id, Input, Run, Private) ->
+    Submit = ide1_dirt:call("createSubmission",
+                            [{"xsd:string", Account#account.user},
+                             {"xsd:string", Account#account.pass},
+                             {"xsd:string", Sourcecode},
+                             {"xsd:int", Language_id},
+                             {"xsd:string", Input},
+                             {"xsd:boolean", atom_to_list(Run)},
+                             {"xsd:boolean", atom_to_list(Private)}]),
+    case lists:keyfind("error", 1, Submit) of
+        {"error", "OK"} ->
+            {"link", Link} = lists:keyfind("link", 1, Submit),
+            {ok, Link};
+        {"error", Anything} ->
+            {error, Anything};
+        Anything ->
+            {error, Anything}
+    end.
+                             
+%%--------------------------------------------------------------------
+%% @doc
+%% @spec
+%% @end
+%%--------------------------------------------------------------------
+get_submission_status(Account, Link) ->
+    Submit = ide1_dirt:call("getSubmissionStatus",
+                            [{"xsd:string", Account#account.user},
+                             {"xsd:string", Account#account.pass},
+                             {"xsd:string", Link}]),
+    case lists:keyfind("error", 1, Submit) of
+        {"error", "OK"} ->
+            {"status", Status} = lists:keyfind("status", 1, Submit),
+            {"result", Result} = lists:keyfind("result", 1, Submit),
+            {ok, Status, Result};
+        {"error", Anything} ->
+            {error, Anything};
+        Anything ->
+            {error, Anything}
+    end.
+
+%%--------------------------------------------------------------------
+%% @doc
+%% @spec
+%% @end
+%%--------------------------------------------------------------------
+get_submission_details(Account, Link) ->
+    Submit = ide1_dirt:call("getSubmissionDetails",
+                            [{"xsd:string", Account#account.user},
+                             {"xsd:string", Account#account.pass},
+                             {"xsd:string", Link},
+                             {"xsd:boolean", "false"},
+                             {"xsd:boolean", "false"},
+                             {"xsd:boolean", "true"},
+                             {"xsd:boolean", "true"},
+                             {"xsd:boolean", "false"}]),
+    case lists:keyfind("error", 1, Submit) of
+        {"error", "OK"} ->
+            {ok, Submit};
+        {"error", Anything} ->
+            {error, Anything};
+        Anything ->
+            {error, Anything}
+    end.    
+
+%%--------------------------------------------------------------------
+%% @doc
+%% @spec
+%% @end
+%%--------------------------------------------------------------------
+evaluate(Account, Sourcecode, erlang) ->
+    [Language_id | _] = [Language_id || {Language_id, Language_name} <- Account#account.language_list,
+                                        string:str(Language_name, "Erlang") /= 0],
+    Expression = lists:flatten(io_lib:format("-module(prog).~n" ++
+                                                 "-export([main/0]).~n" ++
+                                                 "main() ->~n" ++
+                                                 "io:format(\"~~p~~n\",[~s]).~n", [Sourcecode])),
+    case submit(Account, Expression, Language_id, "", true, false) of
+        {ok, Link} ->
+            case wait_for_completion(Account, Link) of
+                {ok, Details} ->
+                    {"output", Output} = lists:keyfind("output", 1, Details),
+                    {ok, Output};
+                Anything ->
+                    Anything
+            end;
+        Anything ->
+            Anything
+    end;
+evaluate(_Account, _Sourcecode, _Language) ->
+    {error, language_not_supported}.
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
+wait_for_completion(Account, Link) ->
+    case get_submission_details(Account, Link) of
+        {ok, Details} ->
+            case lists:keyfind("status", 1, Details) of
+                {"status", 0} ->
+                    {ok, Details};
+                {"status", _} ->
+                    timer:sleep(2000),
+                    wait_for_completion(Account, Link)
+            end;
+        {error, Anything} ->
+            {error, Anything}
+    end.

File src/iderlone.app.src

View file
 {application, iderlone,
  [
-  {description, ""},
-  {vsn, "1"},
+  {description, "A simple Erlang interface to ideone"},
+  {vsn, "0.0.1"},
   {registered, []},
-  {applications, [
-                  kernel,
-                  stdlib
+  {applications, [kernel,
+                  stdlib,
+		  ibrowse
                  ]},
-  {mod, { iderlone_app, []}},
-  {env, []}
+  {modules, [ide1_dirt,
+	     ide1_evaluate]}
  ]}.