How to load the resource file in Erlang - erlang

What is a usual way of storing and loading resource file in Erlang. I need to create a certain human-readable dictionary and load it at application initialization. For example, in Java I would put the data in a .property file, then put it somewhere in the classpath and finally load it with help of code like this:
new Properties().load(Class.getResourceAsStream("/file.properties"))
So, I have the following questions:
where I can (must) keep the resource file?
how to determine in runtime the path to the resource file
how to load it (for example file:consult(Filename))

In Erlang properties are in *.config file, that usually is (but doesn't have to be) in the root directory of your project. For example:
Chicago Boss has boss.config
RabbitMQ has rabbitmq.config
Zotonic has different configs for different sites stored in priv/sitename/config
You can provide config file by running
erl -config myconfig
WARNING: the file should be named "myconfig.config" and you should omit the extension.
The config file should be structured this way:
[{Application1, [{Par11,Val11},...]},
...,
{ApplicationN, [{ParN1,ValN1},...]}].
for example:
[{kernel, [
{my_key, "value"}
]}].
Than in erlang shell, you can type:
application:get_env(kernel, my_key).
{ok,"value"}
I used kernel application, because it is always loaded and application:get_env/2 returns undefined, if the application is not loaded. You should put any configs in your own application and make sure, that it is loaded before invoking get_env/2.
Also, configs are hierarchical, you can put the defaults in *.app file, that user usually doesn't have to modify. You can overwrite them in config file and finally, you can provide the key value pairs in command line (they will overwrite things, that are in config file).
You can read more about configuration here:
http://www.erlang.org/doc/design_principles/applications.html#id74398
You can also make config file more user friendly by using comments, example:
https://github.com/ChicagoBoss/ChicagoBoss/blob/master/skel/boss.config

I found the answer myself. The prefered path to store resource files is a priv directory. code:priv_dir/1 returns the path to the priv directory in an application.
Here is a code snippet to load JSON from the file:
File = filename:join([code:priv_dir(application), "resource.json"]),
{ok, Text} = file:read_file(File),
%% parse json

Related

Erlang : exception error: no match of right hand side value {error,enoent} while reading a text file

I am currenly working on an erlang project and stuck in reading the file. I want to read a text file which is in the /src folder where all the erlang and a text file are in the same structure. Then too, I am not being able to read the file despite of specifying file paths. Any help would be appreciated.
start() ->
{ok,DataList} = file:consult("Calls.txt"),
io:format("** Calls to be made **"),
io:fwrite("~w~n",[DataList]).
The data file stores contents like : {john, [jill,joe,bob]}.
Try add folder name to the path or try set full patch to the file:
1> {ok,DataList} = file:consult("src/Calls.txt").
Notes: the error {error,enoent} mean that the file does not exist or you don't have a rights to read/write current file, for this case need set 777 rights or similar.
If you need to use src/call.txt, then this simply means that your IDE (or you) has created a src folder in which the calls.txt file has been placed. At the same time, the IDE is using a path that only includes the top level folder (i.e., the root folder for the IDE project). So src/call.txt must be used in that case. This isn’t a problem with Erlang, or even the IDE. It’s just the way your project is set up.
You can do either of two things. Move the calls.txt file up one level in the IDE file manager, so that it can be referenced as calls.txt, not src/call.txt. You can also just change the path to “calls.txt” before you run it from the command line.
enoent means "Error: No Entry/Entity". It means the file couldn't be found. When I try your code, it works correctly and outputs
[{john,[jill,joe,bob]}]

Generate URL of resources that are handled by Grails AssetPipeline

I need to access a local JSON file. Since Grails 2.4 implements the AssetPipeline plugin by default, I saved my local JSON file at:
/grails-app/assets/javascript/vendor/me/json/local.json
Now what I need is to generate a URL to this JSON file, to be used as a function parameter on my JavaScript's $.getJSON() . I've tried using:
var URL.local = ""${ raw(asset.assetPath(src: "local.json")) }";
but it generates an invalid link:
console.log(URL.local);
// prints /project/assets/local.json
// instead of /project/assets/vendor/me/json/local.json
I also encountered the same scenario with images that are handled by AssetPipeline1.9.9— that are supposed to be inserted dynamically on the page. How can I generate the URL pointing this resource? I know, I can always provide a static String for the URL, but it seems there would be a more proper solution.
EDIT
I was asked if I could move the local JSON file directly under the assets/javascript root directory instead of placing it under a subdirectory to for an easier solution. I prefer not to, for organization purposes.
Have you tried asset.assetPath(src: "/me/json/local.json")
The assets plugin looks in all of the immediate children of assets/. Your local.json file would need to be placed in /project/assets/foo/ for your current code to pick it up.
Check out the relevant documentation here which contains an example.
The first level deep within the assets folder is simply used for organization purposes and can contain folders of any name you wish. File types also don't need to be in any specific folder. These folders are omitted from the URL mappings and relative path calculations.

Flume "Spooling Directory Source" recursive-look for the the files within subdirectories

I am looking for the Flume "Spooling Directory Source" recursive-look for the the files within subdirectories.
There are some references here https://issues.apache.org/jira/browse/FLUME-1899
however since then multiple versions have come out, is there any way we can have recursive directory lookup within subdirectories for the files in Spooling Source.
I think you can use the patch FLUME-1899-2.patch directly.
set the "recursiveDirectorySearch" as ture in your config file.
NOTE: the regex in ignorePattern of config file will also affect the recursiveDirectory folder name. so you might need to modify the code in org/apache/flume/client/avro/ReliableSpoolingFileEventReader.java if you want to ignore the folder name.

Get config value from file, or environment variable if file doesn't exist

I'm trying to get a setting from a configuration file (preferably something simple like .ini or JSON, not XML). If the file or setting does not exist, I want to be able to fall back to retrieving an environment variable.
I'd prefer to use an existing library for working with JSON/INI and not parsing the file myself. However, most libraries I've found won't work if a file doesn't exist.
How would I access a configuration value from a file that may or may not exist in F#?
You can use File.Exists to test whether or not the file exists:
open System.IO
let getConfig file =
if File.Exists file
then "config from file"
else "config from somewhere else"
OpenExeConfiguration (despite it's name) can open an arbitrary config file.
There's also the ASP.NET vNext Configuration stuff, outlined in this article which is quite flexible - no idea how separable (or relevant to your actual use case) it is [aside from the fact that you could conditionally include the config file into the config manager depending on whether it exists a la Mark's answer].
In addition to type providers, FSharp.Data provides some basic parsers, including JSON. This allows you to do a runtime check using File.Exists and then parse using your preferred utility.
I took the following approach in FAKE:
if File.Exists "local.json" then
let localVarProps = JsonValue.Parse(File.ReadAllText"local.json").Properties
for key, jsonValue in localVarProps do
setEnvironVar key (jsonValue.AsString())

Using custom Environment Variables in JetBrains products for File watcher Arguments

I am trying to use node-sass as File Watcher in WebStorm.
I created a local variable named STYLE with main stylesheet name inside to add it as variable to File Watcher settings everywhere it needed.
But if I add $STYLE$ in a Path I get an error:
/Users/grawl/Sites/sitename/node_modules/node-sass/bin/node-sass app/styles/$STYLE$.scss public/$STYLE$.css
error reading file "app/styles/$STYLE$.scss"
Process finished with exit code 1
IDE just don't interprets my variable.
Also I tried to use %STYLE% but with no luck.
Please do not blame me for direct mapping filenames in File Watcher without using built-in variables like $FileName$ or $FileNameWithoutExtension$ because even WebStorm 9 EAP does not support preprocessor's dependencies except of built-in preprocessors like Sass and Jade.
This case is not only case to use local variables.
For example I want to put into variables my public/ path (that can be dest/ in other projects) and app/ (can be source/). And so on.
So let's figure out this feature.

Resources