Advertisement
Guest User

Untitled

a guest
May 2nd, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 8.22 KB | None | 0 0
  1. -module(finders_lib).
  2.  
  3. -export([
  4.     get_finders/0,
  5.     set_finder_configuration/1,
  6.     batch_export_finders/0,
  7.     batch_export_finders/1,
  8.     batch_import_finders/0,
  9.     batch_import_finders/1
  10. ]).
  11.  
  12. -define(DB_FINDERS_TABLE, "finders").
  13. -define(USB_PATH, "/media/usb0/").
  14. -define(FINDERNAME_START, "finder_").
  15. -define(FINDERNAME_END, ".fnd").
  16.  
  17. % Retrieve finders data from the database
  18. get_finders() ->
  19.     Finders = boss_db:find_by_sql(finder, "SELECT * FROM " ++ ?DB_FINDERS_TABLE),
  20.     prepare_finders_data_for_output(Finders).
  21.  
  22. % Save finder configuration
  23. % Example input:
  24. % finders_lib:set_finder_configuration(
  25. %           {finder_type, <<"onh">>},
  26. %           {eye, <<"od">>},
  27. %           {fixation_label, <<"central">>},
  28. %           {x_pix, 900},
  29. %           {y_pix, 700},
  30. %           {radius_pix, 300},
  31. %           {color, [
  32. %                       {red, 255},
  33. %                       {green, 255},
  34. %                       {blue, 0}
  35. %                   ]
  36. %           }
  37. %     }
  38.  
  39. set_finder_configuration(InputConfig) ->
  40.     lager:notice("~p: Setting finder configuration = ~p", [?MODULE, InputConfig]),
  41.     Type = proplists:get_value(finder_type, InputConfig),
  42.     Eye = proplists:get_value(eye, InputConfig),
  43.     FixationLabel = proplists:get_value(fixation_label, InputConfig),
  44.     FixationTargetId = case boss_db:find(fixation_target, [{label, equals, FixationLabel}], [{limit, 1}]) of
  45.         [FixationTarget] ->
  46.           lager:notice("~p: Fixation target ID = ~p", [?MODULE, FixationTarget:id()]),
  47.           FixationTarget:id();
  48.         _ ->
  49.           lager:notice("~p: default fixation target id", [?MODULE]),
  50.           default_finder_fixation_target_id()
  51.     end,
  52.     InputFinder = case boss_db:find(finder, [{finder_type, equals, Type}, {eye, equals, Eye}, {fixation_target_id, equals, FixationTargetId}]) of
  53.           [Finder] ->
  54.             Finder;
  55.           _ ->
  56.             undefined
  57.         end,
  58.     FinderId = update_or_create_finder(InputConfig, InputFinder),
  59.     {set_finder_configuration, ok}.
  60.  
  61. batch_export_finders() ->
  62.   batch_export_finders(?USB_PATH).
  63.  
  64. batch_export_finders(BasePath) ->
  65.   ExportPath = format_path_with_slash(BasePath),
  66.  
  67.   Finders = boss_db:find_by_sql(finder, "SELECT * FROM " ++ ?DB_FINDERS_TABLE),
  68.   lager:notice("~p: Exporting on ~p finders ~p", [?MODULE, BasePath, Finders]),
  69.  
  70.   Result = lists:map(fun(Finder) ->
  71.     FixationLabel = get_fixation_label(Finder:fixation_target_id()),
  72.     ExportFile = ExportPath ++ ?FINDERNAME_START ++ lists:flatten(io_lib:format("~s", [gsd_utils:sanitize(Finder:finder_type())])) ++ "_" ++
  73.     lists:flatten(io_lib:format("~s", [gsd_utils:sanitize(Finder:eye())])) ++ "_" ++
  74.     lists:flatten(io_lib:format("~s", [gsd_utils:sanitize(FixationLabel)])) ++ ?FINDERNAME_END,
  75.     lager:notice("~p: File name = ~p", [?MODULE, ExportFile]),
  76.     OutputData = serialize_finder_data(Finder),
  77.     case file:write_file(ExportFile, OutputData) of
  78.       ok -> ok;
  79.       _ -> error
  80.     end
  81.  end, Finders),
  82.  
  83.   os:cmd("sync"),
  84.   lager:notice("~p: Export completed", [?MODULE]),
  85.   {export_protocols, Result}.
  86.  
  87. batch_import_finders() ->
  88. batch_import_finders(?USB_PATH).
  89.  
  90. batch_import_finders(BasePath) ->
  91.   FileNames = gsd_file_lib:list_filter_files(?USB_PATH, ?FINDERNAME_START, ?FINDERNAME_END),
  92.   lager:notice("~p: Importing from ~p finders ~p", [?MODULE, BasePath, FileNames]),
  93.   Result = lists:map( fun(FileName) ->
  94.     case file:read_file(FileName) of
  95.       {ok, FileContent} ->
  96.         try deserialize_data(FileContent) of
  97.           _ ->
  98.             case set_finder_configuration(deserialize_data(FileContent)) of
  99.               {set_finder_configuration, ok} ->
  100.                 ok;
  101.               _ ->
  102.                 error
  103.               end
  104.         catch
  105.           Exception:Reason ->
  106.             lager:notice("~p: Exception ~p, with the following reason ~p", [?MODULE, Exception, Reason]),
  107.             error
  108.         end;
  109.       _ ->
  110.         error
  111.       end
  112.   end, FileNames),
  113.   lager:notice("~p: Import completed", [?MODULE]),
  114.   {batch_import_finders, Result}.
  115.  
  116. %%%%%%%%%%%%%%%%%%%%%%%%%
  117. %    PRIVATE SECTION    %
  118. %%%%%%%%%%%%%%%%%%%%%%%%%
  119.  
  120. % Updates an existing finder with the provided data or creates a new one if InputFinder is undefined
  121. update_or_create_finder(FinderConfig, InputFinder) ->
  122.   RecordData = prepare_finder_input_data(FinderConfig),
  123.   Id = case InputFinder of
  124.     undefined ->
  125.       lager:notice("~p: New finder will be created", [?MODULE]),
  126.       NewRecord = boss_record:new(finder, RecordData),
  127.       case NewRecord:save() of
  128.         {ok, Record} ->
  129.           Record:id(),
  130.           ok;
  131.         Error ->
  132.           lager:notice("~p: Error saving record ~p", [?MODULE, Error]),
  133.           error
  134.       end;
  135.     _ ->
  136.       lager:notice("~p: Finder ~p will be updated", [?MODULE, InputFinder]),
  137.       UpdatedFinder = InputFinder:set(RecordData),
  138.       {ok, _} = UpdatedFinder:save(),
  139.       InputFinder:id(),
  140.       ok
  141.   end,
  142.   Id.
  143.  
  144. % Parses input data to be later used to create or update a finder
  145. prepare_finder_input_data(Data) ->
  146.   FixationLabel = proplists:get_value(fixation_label, Data),
  147.   lager:notice("~p: Fixation label = ~p", [?MODULE, FixationLabel]),
  148.   FixationTargetId = case boss_db:find(fixation_target, [{label, equals, FixationLabel}], [{limit, 1}]) of
  149.     [FixationTarget] ->
  150.       lager:notice("~p: Fixation target ID = ~p", [?MODULE, FixationTarget:id()]),
  151.       FixationTarget:id();
  152.     _ ->
  153.       lager:notice("~p: default fixation target id", [?MODULE]),
  154.       default_finder_fixation_target_id()
  155.   end,
  156.   Color = proplists:get_value(color, Data),
  157.   [
  158.     {finder_type, proplists:get_value(finder_type, Data)},
  159.     {eye, proplists:get_value(eye, Data)},
  160.     {fixation_target_id, FixationTargetId},
  161.     {x_pix, proplists:get_value(x_pix, Data)},
  162.     {y_pix, proplists:get_value(y_pix, Data)},
  163.     {radius_pix, proplists:get_value(radius_pix, Data)},
  164.     {red, proplists:get_value(red, Color)},
  165.     {green, proplists:get_value(green, Color)},
  166.     {blue, proplists:get_value(blue, Color)}
  167.   ].
  168.  
  169. % Prepares the finders' data for output
  170. prepare_finders_data_for_output(Finders) ->
  171.     lists:foldl(fun(F, Acc) ->
  172.         FixationLabel = get_fixation_label(F:fixation_target_id()),
  173.         Acc ++
  174.         [[
  175.             {id,                  F:id()},
  176.             {finder_type,         F:finder_type()},
  177.             {eye,                 F:eye()},
  178.             {fixation_label,      FixationLabel},
  179.             {x_pix,               F:x_pix()},
  180.             {y_pix,               F:y_pix()},
  181.             {radius_pix,          F:radius_pix()},
  182.             {color, [
  183.                 {red,             F:red()},
  184.                 {green,           F:green()},
  185.                 {blue,            F:blue()}
  186.             ]}
  187.         ]] end, [], Finders).
  188.  
  189. % Retrieves default fixation target for finder (central fixation)
  190. default_finder_fixation_target_id() ->
  191.   FixationTarget = boss_db:find_first(fixation_target, [{label, equals, "central"}]),
  192.   FixationTarget:id().
  193.  
  194. % Retrieves default fixation label for finder (central fixation)
  195. default_finder_fixation_label() ->
  196.   FixationTarget = boss_db:find_first(fixation_target, [{label, equals, "central"}]),
  197.   FixationTarget:label().
  198.  
  199. % Retrieves fixation label from the fixation target id
  200. get_fixation_label(FixationTargetId) ->
  201.   FixationLabel = case boss_db:find(fixation_target, [{id, equals, FixationTargetId}], [{limit, 1}]) of
  202.     [FixationTarget] ->
  203.       FixationTarget:label();
  204.     _ ->
  205.       default_finder_fixation_label()
  206.     end.
  207.  
  208. format_path_with_slash(InputPath) ->
  209.   case string:right(InputPath, 1) of
  210.       "/" ->
  211.         InputPath;
  212.       _ ->
  213.         InputPath ++ "/"
  214.     end.
  215.  
  216. % Returnes binary-serialized finder data
  217. serialize_finder_data(F) ->
  218.   FixationLabel = get_fixation_label(F:fixation_target_id()),
  219.   Data =
  220.     [[
  221.       {finder_type,           F:finder_type()},
  222.       {eye,                   F:eye()},
  223.       {fixation_label,        FixationLabel},
  224.       {x_pix,                 F:x_pix()},
  225.       {y_pix,                 F:y_pix()},
  226.       {radius_pix,            F:radius_pix()},
  227.       {color, [
  228.         {red,                   F:red()},
  229.         {green,                 F:green()},
  230.         {blue,                  F:blue()}
  231.       ]}
  232.     ]],
  233.   serialize_data(Data).
  234.  
  235. % Generic serialization of data
  236. serialize_data(Data) ->
  237.   erlang:term_to_binary(Data).
  238.  
  239. % Receives binary-serialized input and returns erlang-deserialized data
  240. deserialize_data(Input) ->
  241.   erlang:binary_to_term(Input).
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement