<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -33,6 +33,7 @@
 -define(AUDITFILE,&quot;audit.log&quot;).
 -define(DOCROOT,&quot;www&quot;).
 -define(REACTORS,&quot;reactors&quot;).
+-define(TEMP,&quot;temp&quot;).
 -define(PUBLIC,&quot;/_public/&quot;).
 -define(LOGIN,&quot;/_login&quot;).
 -define(LOGOUT,&quot;/_logout&quot;).</diff>
      <filename>Reactor/include/system.hrl</filename>
    </modified>
    <modified>
      <diff>@@ -99,6 +99,8 @@ handle_call({path,Res}, _From, Conf) -&gt;
 		    Home ++ ?REACTORS ++ &quot;/&quot;;
 		audit -&gt;
 		    Home ++ ?AUDITFILE;
+		temp -&gt;
+		    Home ++ ?TEMP ++ &quot;/&quot;; 
 		_ -&gt;
 		    Home
 		end,</diff>
      <filename>Reactor/src/core/config_server.erl</filename>
    </modified>
    <modified>
      <diff>@@ -149,10 +149,67 @@ react_to('POST',?LOGIN,Request,DocRoot) -&gt;
 	    rest_helper:show_login_form(Request,Error)
     end; 
 
-
 %% Reactor Resource dispatcher
 react_to(Method,?RESOURCES,Request, DocRoot) -&gt;
     Request:respond({501, [], []});
+
+react_to('POST',?RESOURCES ++ Path,Request, DocRoot) -&gt;
+    Credentials = rest_helper:credentials(Request),
+    case lists:last(Path) of
+	$/ -&gt;
+	    R = case string:tokens(Path, &quot;/&quot;) of
+			   [_] -&gt;
+			       Path;
+			   R1 -&gt; 
+			       string:join(R1,&quot;/&quot;)
+		       end,
+	    case actor_server:lookup(rest_helper:qres(R,Request)) of
+		[] -&gt;
+		    rest_helper:error(html_adaptor,create,Path,Request,&quot;Cannot create Upload resource as child of unknown resource/domain &quot; ++ R);
+		Qitem -&gt;
+		    case identity_server:authorise(Credentials,rest_server,create,{Qitem,[]}) of 
+			{ok,_Actor} -&gt;
+			    case upload:store(Path,Request) of
+				{ok,File,Title,Link,Type} -&gt;
+				    io:format(&quot;Uploaded ~s~n&quot;,[File]),
+
+				    [Domain,Res] = string:tokens(Qitem,?DOMAINSEPERATOR),
+				    R2 = case Res of 
+					     &quot;/&quot; -&gt;
+						 Res;
+					     _ -&gt;
+						 Res ++ &quot;/&quot;
+					 end,
+				    Item = R2 ++ &quot;upload_&quot; ++ attribute:today(),
+				    Attributes = [{&quot;title&quot;,Title},{&quot;description&quot;,rest_helper:link(Title,&quot;/&quot; ++ Link) ++ &quot; uploaded resource &quot;},{&quot;type&quot;,rest_helper:safeUri(Type)}],
+				    case actor_server:create(Credentials,?MODULE,Domain,Item,Attributes) of
+					{ok,_Xref} -&gt;
+					    Request:respond({200,[{&quot;Content-Type&quot;,&quot;text/html&quot;}],rest_helper:html(&quot;&lt;h1&gt;File uploaded&lt;/h1&gt;&quot;)});
+					{autherror,Why} -&gt;
+					    error({&quot;Authentication Error adding upload&quot;,Why,Title}),
+					    rest_helper:forbidden(html_adaptor,'POST',?RESOURCES ++ Path,Request,&quot;&lt;h1&gt;Sorry but you do not have access privelages to upload here&lt;/h1&gt;&quot;);
+					{error,Error} -&gt;
+					    error({&quot;Error adding upload message&quot;,Error,Title}),
+					    rest_helper:error(html_adaptor,'POST',?RESOURCES ++ Path,Request,&quot;&lt;h1&gt;Sorry an error occured uploading your file&lt;/h1&gt;&quot;)
+				    end;    
+			    {error,Error,Resp} -&gt;
+				error({&quot;Uploading error&quot;,Error,Resp}),
+				rest_helper:error(html_adaptor,'POST',?RESOURCES ++ Path,Request,&quot;&lt;h1&gt;Sorry an error occured uploading your file&lt;/h1&gt;&quot;);
+			    _ -&gt; 
+				error({&quot;Upload failure&quot;,Path}),
+				rest_helper:error(html_adaptor,'POST',?RESOURCES ++ Path,Request,&quot;&lt;h1&gt;Sorry an error occured uploading your file&lt;/h1&gt;&quot;)
+			    end;
+			{error,Actor,Why} -&gt;
+			    error(Why),
+			    rest_helper:forbidden(?RESOURCES ++ Path,Request,&quot;You do not have the access privelages to upload to this resource&quot;)
+		    end
+		end;
+	_ -&gt;
+	    error({&quot;Upload failure cannot upload to Resource &quot;,Path}),
+	    rest_helper:error(html_adaptor,'POST',?RESOURCES ++ Path,Request,&quot;&lt;h1&gt;Sorry an error occured uploading your file&lt;/h1&gt;&quot;)
+    end;
+
+
 react_to(Method,?RESOURCES ++ Path,Request, DocRoot) -&gt;
     [Dom|Resource] = string:tokens(Path,&quot;/&quot;),
     Domain = rest_helper:qres(Dom,Request),
@@ -175,14 +232,6 @@ react_to(Method,?RESOURCES ++ Path,Request, DocRoot) -&gt;
 			    end
 			    
 		    end;
-		'POST' -&gt;
-		    case Path of
-			_ -&gt;
-						%ToDo this must move teh temp file to ?RESOURCES sub dir and domain hierarchy
-			    Res = upload:store(Request),
-			    io:format(&quot;Upload response ~p~n&quot;,[Res]),
-			    Request:respond({200,[{&quot;Content-Type&quot;,&quot;text/html&quot;}],rest_helper:html(&quot;&lt;h1&gt;uploaded&lt;/h1&gt;&quot;)})
-		    end;
 		_ -&gt;
 		    Request:respond({501, [], []})
 	    end</diff>
      <filename>Reactor/src/core/rest_server.erl</filename>
    </modified>
    <modified>
      <diff>@@ -3,16 +3,41 @@
 -include(&quot;system.hrl&quot;).
 -define(DOSSEPERATOR,&quot;\\&quot;).
 -define(UNIXSEPERATOR,&quot;/&quot;).
--export([store/1]).
+-export([store/2,filename/1,name_to_path/2]).
 
-store(Req) -&gt;
-    reactor_parse_form(Req).
+store(Path,Req) -&gt;
+    reactor_parse_form(Path,Req).
 
-reactor_parse_form(Req) -&gt;
-    mochiweb_multipart:parse_form(Req,fun reactor_file_handler/2).
+reactor_parse_form(Path,Req) -&gt;
+    io:format(&quot;Uploader file handler uploading to ~s~n&quot;,[Path]),
+    case mochiweb_multipart:parse_form(Req,fun reactor_file_handler/2) of
+	[{_Field1,{Filename,ContentType,Temp}},{_Field2,Title},{_Submit,_Submitval}] -&gt; 
+	    move_upload(Filename,Path,Temp,ContentType,Title);
+	[{_Field2,Title},{_Field1,{Filename,ContentType,Temp}},{_Submit,_Submitval}] -&gt; 
+	    move_upload(Filename,Path,Temp,ContentType,Title);
+	[{_Field2,Title},{_Field1,{Filename,ContentType,Temp}}] -&gt; 
+	    move_upload(Filename,Path,Temp,ContentType,Title);
+	Res -&gt; {error,&quot;Unknown error&quot;,Res}
+    end.
+
+move_upload(Filename,Path,Temp,ContentType,Title) -&gt;
+    io:format(&quot;Moving uploaded file ~s~n&quot;,[Filename]),
+    case name_to_path(filename(Filename),Path) of
+	{ok,Dest} -&gt;
+	    case file:rename(Temp, Dest) of
+		ok -&gt; 
+		    {Type,_} = ContentType,
+		    {ok,Dest,Title,Dest -- config_server:path(docroot),Type};
+		{error,Error} -&gt; 
+		    {error, &quot;File upload internal transfer failed : &quot; ++ Dest ++ &quot;, Error : &quot; ++ atom_to_list(Error)}
+	    end;
+	{error,Error} -&gt;
+	    {error, &quot;File upload failed : &quot; ++ Filename ++ &quot;, Reason : &quot; ++ atom_to_list(Error)}
+    end.
 
 reactor_file_handler(Filename,ContentType) -&gt;
-    Temp = uid() ++ &quot;.temp&quot;,
+    Temp = config_server:path(temp) ++ uid() ++ &quot;.tmp&quot;,
+    io:format(&quot;Creating temp upload file ~s~n&quot;,[Temp]),
     case file:open(Temp,[raw,write]) of
 	{ok, File} -&gt;
 	    reactor_file_handler_1(Filename,ContentType,File,Temp);
@@ -35,18 +60,24 @@ reactor_file_handler_1(Filename,ContentType,File,Temp) -&gt;
 % Utility functions for uploader
 filename(&quot;/&quot; ++ Path) -&gt; 
     name_from_path(Path,?UNIXSEPERATOR);
-filename([Drive|Path]) when hd(Path) =:= $: -&gt; 
-    name_from_path(Path,?DOSSEPERATOR).
+filename(&quot;./&quot; ++ Path) -&gt;
+    name_from_path(Path,?UNIXSEPERATOR);
+filename(&quot;../&quot; ++ Path) -&gt;
+    name_from_path(Path,?UNIXSEPERATOR);
+filename([_Drive|Path]) when hd(Path) =:= $: -&gt; 
+    name_from_path(Path,?DOSSEPERATOR);
+filename(Path) -&gt;
+    name_from_path(Path,?UNIXSEPERATOR).
 
 name_from_path(Path,Seperator) -&gt;
-    hd(list:reverse(string:tokens(Path,Seperator))).
+    hd(lists:reverse(string:tokens(Path,Seperator))).
 
 safe(Name) -&gt;
     {_,S,_} = regexp:gsub(Name,&quot;[^a-zA-Z0-9\-_\.]+&quot;,&quot;_&quot;),
     S.
 
 name_to_path(Name,Parent) -&gt;
-    case create_path(string:tokens(Parent,&quot;/&quot;),config_server:path(docroot) ++ ?RESOURCES) of
+    case create_path(string:tokens(Parent,&quot;/&quot;),rtl(config_server:path(docroot)) ++ rtl(?RESOURCES)) of
 	{ok,Path} -&gt;
 	    {ok,Path ++ &quot;/&quot; ++ uid() ++ extension(Name)};
 	{error,Reason} -&gt;
@@ -54,7 +85,7 @@ name_to_path(Name,Parent) -&gt;
     end.
 
 create_path([Item|Items],Path) -&gt;
-    case file:make_dir(Path ++ Item) of 
+    case file:make_dir(Path ++ &quot;/&quot; ++ Item) of 
 	ok -&gt;
 	    create_path(Items,Path ++ &quot;/&quot; ++ Item);
 	{error,eexist} -&gt;
@@ -71,8 +102,11 @@ extension(Name) -&gt;
 	0 -&gt;
 	    &quot;&quot;;
 	_ -&gt;
-	    hd(list:reverse(string:tokens(Name,&quot;.&quot;)))
+	    [$.|hd(lists:reverse(string:tokens(Name,&quot;.&quot;)))]
     end.
 
 uid() -&gt;
     attribute:today().
+
+rtl(L) -&gt;
+    lists:reverse(tl(lists:reverse(L))).</diff>
      <filename>Reactor/src/core/upload.erl</filename>
    </modified>
    <modified>
      <diff>@@ -30,7 +30,7 @@
 -include(&quot;system.hrl&quot;).
 -include_lib(&quot;stdlib/include/qlc.hrl&quot;).
 -export([respond/2,error/5,redirect/4,unauthorised/2,forbidden/3]).
--export([a/1,qres/2,domain/1,attributes/2,safe_char_set/1,show_login_form/1,show_login_form/2,q/1,repack_acl/3,tag/5,html/1,split/1,item_to_url/1,title/1,safeUri/1,accepts/1,attributes_and_actor/2,credentials/1,cookie/3,cookie_options/2,save_session/2,remove_session/1,get_credentials/1,add_credentials/1,get_option/2,qualified/2]).
+-export([a/1,qres/2,domain/1,attributes/2,safe_char_set/1,show_login_form/1,show_login_form/2,q/1,repack_acl/3,tag/5,html/1,split/1,item_to_url/1,title/1,safeUri/1,accepts/1,attributes_and_actor/2,credentials/1,cookie/3,cookie_options/2,save_session/2,remove_session/1,get_credentials/1,add_credentials/1,get_option/2,qualified/2,link/2]).
 
 %% Response support functions
 respond(Request,{ContentType,Body}) -&gt;
@@ -132,6 +132,8 @@ credentials(Request) -&gt;
 	    get_credentials(UserId)
     end.
 
+
+
 cookie(Cookie,UserId,Options) -&gt;
     mochiweb_cookies:cookie(Cookie,UserId,Options).
 
@@ -320,3 +322,6 @@ item_to_url(Item) -&gt;
 
 qualified(Domain,Item) -&gt;
     attribute:item_id(Domain,Item).
+
+link(Title,Link) -&gt;
+    &quot;&lt;a href=\&quot;&quot; ++ Link ++ &quot;\&quot; title=\&quot;&quot; ++ Title ++ &quot;\&quot;&gt;Download&lt;/a&gt;&quot;.</diff>
      <filename>Reactor/src/rest/rest_helper.erl</filename>
    </modified>
    <modified>
      <diff>@@ -32,4 +32,3 @@ puts &quot;Adding users : \n&quot;
 temp = root.each_element('//user') {|entry| add_user(entry,reactor,domain)}
 puts &quot;updating acls : \n&quot; 
 temp = root.each_element('//acl') {|entry| add_acl(entry,reactor,domain)}
-</diff>
      <filename>interfaces/ruby/src/import_acl.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>765a31fc1d967e5199a675045a5a57406a63973d</id>
    </parent>
  </parents>
  <author>
    <name>Alan Wood</name>
    <email>al@folknology.com</email>
  </author>
  <url>http://github.com/folknology/reactored/commit/f8c46dbf61fcb3c9f56198befcfda3e2899cff74</url>
  <id>f8c46dbf61fcb3c9f56198befcfda3e2899cff74</id>
  <committed-date>2009-03-19T17:34:53-07:00</committed-date>
  <authored-date>2009-03-19T17:34:53-07:00</authored-date>
  <message>Completed the _resource upload code</message>
  <tree>e1bbe097a60facb920e17cd45ccfa8e53cc4d94a</tree>
  <committer>
    <name>Alan Wood</name>
    <email>al@folknology.com</email>
  </committer>
</commit>
