1

I am running a riak cluster of 5 nodes which i connect to through a protocol buffer client riak-erlang-client. I installed riak-erlang-client as a nitrogen plugin as i suggested at this stackoverflow link. I know how to upload files through the nitrogen web-framework after then i try to store them in the riak database and later i retrieve them.

I have looked at this highlight shown at Basho resources

curl -XPUT http://localhost:10018/buckets/images/keys/<image_name>.jpg -H 'Content-Type: image/jpeg' --data-binary @<image_name>.jpg

But it is not meeting my needs at all since it does not even use the client i am using!!

I have ever used the file libraries of Erlang/OTP to read photo files from the ./scratch directory of nitrogen so as to save the photo files a binary streams in the riak database but i failed to retrieve them to my nitrogen driven web application.

Any help is welcomed.

Community
  • 1
  • 1
  • What code have you written so far? How does it fail? Do you get an error message? – legoscia Jan 22 '15 at 16:09
  • When you stored them via the protocol buffer client, did you add a content type to the metadata so the web app knows how to handle them? – Joe Jan 22 '15 at 20:18
  • @legoscia @Joe I use `{ok, Binary} = file:read_file(Filename)` to read the photo file as a binary stream, then i use `Obj = riakc_obj:new(<<"images">>,<<"Filename">>,Binary)`. I have used these functions `Obj2 = riakc_obj:update_content_type(Obj,<<"image/jpeg">>)` and finally `riakc_pb_socket:put(Pid,Obj2)`. Now retrieving and deserialize the object: `{ok, Obj3} = riakc_pb_socket:get(Pid, <<"images">>, <<"Filename">>),Val = binary_to_term(riakc_obj:get_value(Obj3)), CT = riakc_obj:get_content_type(Obj3)`. How do i use `#image{}`,Val, CT to render the image in the nitrogen page? – Vianney Sserwanga Jan 23 '15 at 03:41
  • `binary_to_term(riakc_obj:get_value(Obj3))` doesn't seem right - you should get back exactly what you put it, i.e. binary image data, not a binary-encoded erlang term. – Joe Jan 23 '15 at 15:00

1 Answers1

0

First add the riak-erlang-client to Nitrogen as a Plugin using rebar. Add a dependency like the one below to the rebar.config in your project. Basho resource

{deps, [
    {riakc, "1.4.1",
      {git, "git://github.com/basho/riak-erlang-client", 
         {tag, "1.4.1"}}}
   ]}.

Then run make in your application

cd ../../myapp
make

Upload the file using for example this Nitrogen upload example. The source code if found here.

In the finish_upload_event section capture the LocalFileName file path in the scratch folder. Use the file path to read the file.

event(_) -> ok.

start_upload_event(Tag) ->
    wf:flash(wf:f("Upload started with tag (~p)", [Tag])).

finish_upload_event(_Tag, undefined, _, _) -> 
   wf:flash("Please select a file."), ok;

finish_upload_event(_Tag, _FileName, LocalFileName, _Node) ->
   {ok, Binary_image} = file:read_file(LocalFileName),

   %% Open a connection to the Riak database
   {ok, Pid} = riakc_pb_socket:start(DBNode,PORT,{connect_timeout,TIMEOUT},auto_reconnect, false}])).

   %% If the bucket where you save your images is called my_images, create the riak object
   Obj = riakc_obj:new(term_to_binary(my_images),term_to_binary(My_key),Binary_image),

   %% Save to the database
   ok = riakc_pb_socket:put(Pid, Obj,[]).

To read the image from the database and display it in the web browser

-module(image).
-include_lib("nitrogen_core/include/wf.hrl").
-compile(export_all).   

main() -> 
   %% Set the content-type of the image
   wf:content_type("image/png"),
   {ok, Pid} = riakc_pb_socket:start(DBNode,PORT,{connect_timeout,TIMEOUT},auto_reconnect, false}])).

   %% Read the image data from the database
   {ok, Fetched} = riakc_pb_socket:get(Pid,     term_to_binary(my_images),term_to_binary(My_key),[]),

   %% Record the image record
   Binary_image = binary_to_term(riakc_obj:get_value(Fetched)),
   Binary_image.        

event(_) -> ok. 

In the browser structure your URL to the image file like http://example.com/image

Where image is the module rendering the image file.