./ct_report/coverage/translate.COVER.html

1 %%%----------------------------------------------------------------------
2 %%% File : translate.erl
3 %%% Author : Alexey Shchepin <alexey@process-one.net>
4 %%% Purpose : Localization helper
5 %%% Created : 6 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
6 %%%
7 %%%
8 %%% ejabberd, Copyright (C) 2002-2011 ProcessOne
9 %%%
10 %%% This program is free software; you can redistribute it and/or
11 %%% modify it under the terms of the GNU General Public License as
12 %%% published by the Free Software Foundation; either version 2 of the
13 %%% License, or (at your option) any later version.
14 %%%
15 %%% This program is distributed in the hope that it will be useful,
16 %%% but WITHOUT ANY WARRANTY; without even the implied warranty of
17 %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 %%% General Public License for more details.
19 %%%
20 %%% You should have received a copy of the GNU General Public License
21 %%% along with this program; if not, write to the Free Software
22 %%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 %%%
24 %%%----------------------------------------------------------------------
25
26 -module(translate).
27 -author('alexey@process-one.net').
28
29 -export([start/0,
30 translate/2]).
31
32 -include("mongoose.hrl").
33
34 -define(MSGS_DIR, "msgs").
35
36 %%
37 %% Public
38 %%
39
40 -spec start() -> 'ok'.
41 start() ->
42 53 ets:new(translations, [named_table, public]),
43 53 ok = load_translations_from_dir(lang_files_directory()),
44 53 ok.
45
46 -spec translate(ejabberd:lang(), binary()) -> binary().
47 translate(Lang, Msg) ->
48 2259 LLang = to_lower(Lang),
49 2259 case get_translation(LLang, Msg) of
50 896 {ok, Trans} -> Trans;
51 1363 {error, not_found} -> get_default_server_lang_translation(Msg)
52 end.
53
54 %%
55 %% Private
56 %%
57
58 -spec lang_files_directory() -> file:filename().
59 lang_files_directory() ->
60 53 case os:getenv("EJABBERD_MSGS_PATH") of
61 false ->
62 53 case code:priv_dir(mongooseim) of
63
:-(
{error, _} -> ?MSGS_DIR;
64 53 Path -> Path
65 end;
66
:-(
Path -> Path
67 end.
68
69 -spec load_translations_from_dir(file:filename()) -> ok.
70 load_translations_from_dir(Dir) ->
71 53 case file:list_dir(Dir) of
72 {ok, Files} ->
73 53 MsgFiles = lists:filter(fun has_msg_extension/1, Files),
74 53 load_translation_files(Dir, MsgFiles);
75 {error, Reason} ->
76
:-(
?LOG_ERROR(#{what => load_translations_from_dir_failed,
77
:-(
directory => Dir, reason => Reason}),
78
:-(
ok
79 end.
80
81 -spec load_translation_files(file:filename(), [file:filename()]) -> ok.
82 load_translation_files(Dir, MsgFiles) ->
83 53 lists:foreach(fun(Filename) ->
84 1325 Lang = lang_from_file_name(Filename),
85 1325 load_file(Lang, Dir ++ "/" ++ Filename)
86 end, MsgFiles).
87
88 -spec lang_from_file_name(file:filename()) -> string().
89 lang_from_file_name(Filename) ->
90 1325 string:to_lower(filename:rootname(Filename)).
91
92 -spec has_msg_extension(file:filename()) -> boolean().
93 has_msg_extension(FileName) ->
94 3392 filename:extension(FileName) == ".msg".
95
96 -spec load_file(string(), file:name()) -> 'ok'.
97 load_file(Lang, File) ->
98 1325 BLang = list_to_binary(Lang),
99 1325 case file:consult(File) of
100 {ok, Terms} ->
101 1325 lists:foreach(fun({Orig, Trans}) ->
102 487653 insert_translation(BLang,
103 unicode:characters_to_binary(Orig),
104 unicode:characters_to_binary(Trans))
105 end, Terms);
106 {error, Reason} ->
107
:-(
ExitText = iolist_to_binary(File ++ ": " ++ file:format_error(Reason)),
108
:-(
?LOG_ERROR(#{what => load_translation_file_failed,
109 text => <<"Problem loading translation file">>,
110
:-(
filename => File, reason => ExitText}),
111
:-(
exit(ExitText)
112 end.
113
114 -spec insert_translation(ejabberd:lang(), binary(), binary()) -> true.
115 insert_translation(Lang, Msg, <<"">>) ->
116
:-(
insert_translation(Lang, Msg, Msg); %% use key if it is not defined
117 insert_translation(Lang, Msg, Trans) ->
118 487653 ets:insert(translations, {{Lang, Msg}, Trans}).
119
120 -spec get_default_server_lang_translation(binary()) -> binary().
121 get_default_server_lang_translation(Msg) ->
122 1363 case get_translation(?MYLANG, Msg) of
123 1363 {ok, DefaultTrans} -> DefaultTrans;
124
:-(
{error, not_found} -> Msg
125 end.
126
127 -spec get_translation(ejabberd:lang(), binary()) -> {ok, binary()} | {error, not_found}.
128 get_translation(LLang, Msg) ->
129 3622 case read_trans(LLang, Msg) of
130 {error, not_found} ->
131 1363 read_trans(short_lang(LLang), Msg);
132 {ok, Trans} ->
133 2259 {ok, Trans}
134 end.
135
136 -spec read_trans(ejabberd:lang(), binary()) -> {ok, binary()} | {error, not_found}.
137 read_trans(<<"en">>, Msg) ->
138 2259 {ok, Msg};
139 read_trans(LLang, Msg) ->
140 2726 case ets:lookup(translations, {LLang, Msg}) of
141
:-(
[{_, Trans}] -> {ok, Trans};
142 2726 _ -> {error, not_found}
143 end.
144
145 -spec short_lang(ejabberd:lang()) -> ejabberd:lang().
146 short_lang(LLang) ->
147 1363 case string:tokens(binary_to_list(LLang), "-") of
148 1363 [] -> LLang;
149
:-(
[ShortLang | _] -> list_to_binary(ShortLang)
150 end.
151
152 -spec to_lower(binary()) -> binary().
153 to_lower(Bin) ->
154 2259 list_to_binary(string:to_lower(binary_to_list(Bin))).
Line Hits Source