<commit_before>%%%-------------------------------------------------------------------
%%% @author <NAME> <<EMAIL>>
%%% @copyright 2011,
%%% @doc Encodes twilio records into an XML document.
%%%
%%% @end
%%%-------------------------------------------------------------------
-module(twiml).

-export([
         encode/1,
         validate/1,
         is_valid/1,
         compile/1,
         compile/2,
         compile/3,
         bump/1,
         unbump/1,
         incr/1,
         decr/1
        ]).

-export([
         testing/0,
         testing2/0,
         testing3/0,
         testing4/0,
         testing5/0,
         testing6/0,
         testing7/0
        ]).

-include("twilio.hrl").

-define(DOLLAR, "$"). %". for the code colouring

%% @doc Encodes a set of twiml records as an XML document.
encode(Elements) ->
    Content = [{'Response', [], [to_xmerl_element(El) || El <- Elements]}],
    xmerl:export_simple(Content, xmerl_xml).

encode_record(Record) ->
    El = xmerl:export_simple([to_xmerl_element(Record)], xmerl_xml),
    "<?xml version=\"1.0\"?>" ++ XML = lists:flatten(El),
    {xml, XML}.

%% @doc Converts a twiml record to an xmerl XML element.
to_xmerl_element(#say{} = Say) ->
    Attrs = [{voice,    Say#say.voice},
             {language, Say#say.language},
             {loop,     Say#say.loop}],
    CleanAttrs = remove_undefined(Attrs),
    {'Say', CleanAttrs, [Say#say.text]};
to_xmerl_element(#play{} = Play) ->
    Attrs = [{loop, Play#play.loop}],
    CleanAttrs = remove_undefined(Attrs),
    {'Play', CleanAttrs, [Play#play.url]};
to_xmerl_element(#gather{} = Gather) ->
    Attrs = [{action,      Gather#gather.action},
             {method,      Gather#gather.method},
             {timeout,     Gather#gather.timeout},
             {finishOnKey, Gather#gather.finishOnKey},
             {numDigits,   Gather#gather.numDigits}],
    CleanAttrs = remove_undefined(Attrs),
    Body = [to_xmerl_element(Element) || Element <- Gather#gather.body],
    {'Gather', CleanAttrs, Body};
to_xmerl_element(#record{} = Record) ->
    Attrs = [{action,             Record#record.action},
             {method,             Record#record.method},
             {timeout,            Record#record.timeout},
             {finishOnKey,        Record#record.finishOnKey},
             {maxLength,          Record#record.maxLength},
             {transcribe,         Record#record.transcribe},
             {transcribeCallback, Record#record.transcribeCallback},
             {playBeep,           Record#record.playBeep}],
    CleanAttrs = remove_undefined(Attrs),
    {'Record', CleanAttrs, []};
to_xmerl_element(#sms{} = Sms) ->
    Attrs = [{to,             Sms#sms.to},
             {from,           Sms#sms.from},
             {action,         Sms#sms.action},
             {method,         Sms#sms.method},
             {statusCallback, Sms#sms.statusCallback}],
    CleanAttrs = remove_undefined(Attrs),
    {'Sms', CleanAttrs, [Sms#sms.text]};
to_xmerl_element(#dial{} = Dial) ->
    Attrs = [{action,       Dial#dial.action},
             {method,       Dial#dial.method},
             {timeout,      Dial#dial.timeout},
             {hangupOnStar, Dial#dial.hangupOnStar},
             {timeLimit,    Dial#dial.timeLimit},
             {callerId,     Dial#dial.callerId},
             {record,       Dial#dial.record}],
    CleanAttrs = remove_undefined(Attrs),

    Body = case Dial#dial.body of
               [] ->
                   [];
               _ ->
                   case is_list(Dial#dial.body) of
                       true ->
                           case is_tuple(hd(Dial#dial.body)) of
                               true -> [to_xmerl_element(X)
                                        || X <- Dial#dial.body];
                               false -> [Dial#dial.body]
                           end;
                       false ->
                           [to_xmerl_element(Dial#dial.body)]
                   end
           end,
    {'Dial', CleanAttrs, Body};
to_xmerl_element(#number{} = Number) ->
    Attrs = [{sendDigits, Number#number.sendDigits},
             {url, Number#number.url}],
    CleanAttrs = remove_undefined(Attrs),
    {'Number', CleanAttrs, [Number#number.number]};
to_xmerl_element(#redirect{} = Redirect) ->
    Attrs = [{method, Redirect#redirect.method}],
    CleanAttrs = remove_undefined(Attrs),
    {'Redirect', CleanAttrs, [Redirect#redirect.url]};
to_xmerl_element(#pause{} = Pause) ->
    Attrs = [{length, Pause#pause.length}],
    CleanAttrs = remove_undefined(Attrs),
    {'Pause', CleanAttrs, []};
to_xmerl_element(#hangup{}) ->
    {'Hangup', [], []};
to_xmerl_element(#reject{} = Reject) ->
    Attrs = [{reason, Reject#reject.reason}],
    CleanAttrs = remove_undefined(Attrs),
    {'Reject', CleanAttrs, []};
to_xmerl_element(#client{} = C) ->
    {'Client', [], [C#client.client]};
to_xmerl_element(#conference{} = C) ->
    Attrs = [{muted,                  C#conference.muted},
             {beep,                   C#conference.beep},
             {startConferenceOnEnter, C#conference.startConferenceOnEnter},
             {endConferenceOnExit,    C#conference.endConferenceOnExit},
             {waitUrl,                C#conference.waitUrl},
             {waitMethod,             C#conference.waitMethod},
             {maxParticipants,        C#conference.maxParticipants}],
    CleanAttrs = remove_undefined(Attrs),
    {'Conference', CleanAttrs, [C#conference.conference]}.

%% @doc Removes any undefined attributes.
remove_undefined(Attrs) ->
    [Attr || {_, Value} = Attr <- Attrs, Value =/= undefined].

compile(Elements) when is_list(Elements) ->
    compile(Elements, "0", fsm).

compile(Elements, Type) when is_list(Elements) ->
    compile(Elements, "1", Type).

compile(Elements, Rank, html) when is_list(Elements) ->
    comp2(Elements, Rank, fun print_html/2);
compile(Elements, Rank, ascii) when is_list(Elements) ->
    comp2(Elements, Rank, fun print_ascii/2);
compile(Elements, Rank, fsm) when is_list(Elements) -><commit_msg>bug fix<commit_after>%%%-------------------------------------------------------------------
%%% @author <NAME> <<EMAIL>>
%%% @copyright 2011,
%%% @doc Encodes twilio records into an XML document.
%%%
%%% @end
%%%-------------------------------------------------------------------
-module(twiml).

-export([
         encode/1,
         validate/1,
         is_valid/1,
         compile/1,
         compile/2,
         compile/3,
         bump/1,
         unbump/1,
         incr/1,
         decr/1
        ]).

-export([
         testing/0,
         testing2/0,
         testing3/0,
         testing4/0,
         testing5/0,
         testing6/0,
         testing7/0
        ]).

-include("twilio.hrl").

-define(DOLLAR, "$"). %". for the code colouring

%% @doc Encodes a set of twiml records as an XML document.
encode(Elements) ->
    Content = [{'Response', [], [to_xmerl_element(El) || El <- Elements]}],
    xmerl:export_simple(Content, xmerl_xml).

encode_record(Record) ->
    El = xmerl:export_simple([to_xmerl_element(Record)], xmerl_xml),
    "<?xml version=\"1.0\"?>" ++ XML = lists:flatten(El),
    {xml, XML}.

%% @doc Converts a twiml record to an xmerl XML element.
to_xmerl_element(#say{} = Say) ->
    Attrs = [{voice,    Say#say.voice},
             {language, Say#say.language},
             {loop,     Say#say.loop}],
    CleanAttrs = remove_undefined(Attrs),
    {'Say', CleanAttrs, [Say#say.text]};
to_xmerl_element(#play{} = Play) ->
    Attrs = [{loop, Play#play.loop}],
    CleanAttrs = remove_undefined(Attrs),
    {'Play', CleanAttrs, [Play#play.url]};
to_xmerl_element(#gather{} = Gather) ->
    Attrs = [{action,      Gather#gather.action},
             {method,      Gather#gather.method},
             {timeout,     Gather#gather.timeout},
             {finishOnKey, Gather#gather.finishOnKey},
             {numDigits,   Gather#gather.numDigits}],
    CleanAttrs = remove_undefined(Attrs),
    Body = [to_xmerl_element(Element) || Element <- Gather#gather.body],
    {'Gather', CleanAttrs, Body};
to_xmerl_element(#record{} = Record) ->
    Attrs = [{action,             Record#record.action},
             {method,             Record#record.method},
             {timeout,            Record#record.timeout},
             {finishOnKey,        Record#record.finishOnKey},
             {maxLength,          Record#record.maxLength},
             {transcribe,         Record#record.transcribe},
             {transcribeCallback, Record#record.transcribeCallback},
             {playBeep,           Record#record.playBeep}],
    CleanAttrs = remove_undefined(Attrs),
    {'Record', CleanAttrs, []};
to_xmerl_element(#sms{} = Sms) ->
    Attrs = [{to,             Sms#sms.to},
             {from,           Sms#sms.from},
             {action,         Sms#sms.action},
             {method,         Sms#sms.method},
             {statusCallback, Sms#sms.statusCallback}],
    CleanAttrs = remove_undefined(Attrs),
    {'Sms', CleanAttrs, [Sms#sms.text]};
to_xmerl_element(#dial{} = Dial) ->
    Attrs = [{action,       Dial#dial.action},
             {method,       Dial#dial.method},
             {timeout,      Dial#dial.timeout},
             {hangupOnStar, Dial#dial.hangupOnStar},
             {timeLimit,    Dial#dial.timeLimit},
             {callerId,     Dial#dial.callerId},
             {record,       Dial#dial.record}],
    CleanAttrs = remove_undefined(Attrs),

    Body = case Dial#dial.body of
               [] ->
                   [];
               _ ->
                   case is_list(Dial#dial.body) of
                       true ->
                           case is_tuple(hd(Dial#dial.body)) of
                               true -> [to_xmerl_element(X)
                                        || X <- Dial#dial.body];
                               false -> [Dial#dial.body]
                           end;
                       false ->
                           [to_xmerl_element(Dial#dial.body)]
                   end
           end,
    {'Dial', CleanAttrs, Body};
to_xmerl_element(#number{} = Number) ->
    Attrs = [{sendDigits, Number#number.sendDigits},
             {url, Number#number.url}],
    CleanAttrs = remove_undefined(Attrs),
    {'Number', CleanAttrs, [Number#number.number]};
to_xmerl_element(#redirect{} = Redirect) ->
    Attrs = [{method, Redirect#redirect.method}],
    CleanAttrs = remove_undefined(Attrs),
    {'Redirect', CleanAttrs, [Redirect#redirect.url]};
to_xmerl_element(#pause{} = Pause) ->
    Attrs = [{length, Pause#pause.length}],
    CleanAttrs = remove_undefined(Attrs),
    {'Pause', CleanAttrs, []};
to_xmerl_element(#hangup{}) ->
    {'Hangup', [], []};
to_xmerl_element(#reject{} = Reject) ->
    Attrs = [{reason, Reject#reject.reason}],
    CleanAttrs = remove_undefined(Attrs),
    {'Reject', CleanAttrs, []};
to_xmerl_element(#client{} = C) ->
    {'Client', [], [C#client.client]};
to_xmerl_element(#conference{} = C) ->
    Attrs = [{muted,                  C#conference.muted},
             {beep,                   C#conference.beep},
             {startConferenceOnEnter, C#conference.startConferenceOnEnter},
             {endConferenceOnExit,    C#conference.endConferenceOnExit},
             {waitUrl,                C#conference.waitUrl},
             {waitMethod,             C#conference.waitMethod},
             {maxParticipants,        C#conference.maxParticipants}],
    CleanAttrs = remove_undefined(Attrs),
    {'Conference', CleanAttrs, [C#conference.conference]}.

%% @doc Removes any undefined attributes.
remove_undefined(Attrs) ->
    [Attr || {_, Value} = Attr <- Attrs, Value =/= undefined].

compile(Elements) when is_list(Elements) ->
    compile(Elements, "1", fsm).

compile(Elements, Type) when is_list(Elements) ->
    compile(Elements, "1", Type).

compile(Elements, Rank, html) when is_list(Elements) ->
    comp2(Elements, Rank, fun print_html/2);
compile(Elements, Rank, ascii) when is_list(Elements) ->
    comp2(Elements, Rank, fun print_ascii/2);
compile(Elements, Rank, fsm) when is_list(Elements) ->
{'fraction_non_alphanumeric': 0.16837578564340058, 'fraction_numerical': 0.005788951372808469, 'mean_word_length': 2.0067130780706117, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 2, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6385234', 'n_tokens_mistral': 3904, 'n_tokens_neox': 3771, 'n_words': 655}