<commit_before>%% @doc Default
-module(ginger_adlib_elasticsearch_mapping).

-export([
    map/1,
    map_property/3,
    year/1,
    to_list/1,
    to_labelled_list/1
]).

-include_lib("zotonic.hrl").

-callback map_property(Property :: binary(), Value :: binary(), Acc :: map()) -> NewAcc :: map().

map(Record) ->
    Record.

map_property(Key, [#{<<"value">> := Value}], Acc) ->
    %% Flatten Adlib's @lang/value xmltype=grouped structure.
    map_property(Key, Value, Acc);
map_property(Key, #{<<"value">> := Value}, Acc) ->
    %% Flatten Adlib's @lang/value xmltype=grouped structure.
    map_property(Key, Value, Acc);
map_property(Key, Value, Acc) when Key =:= <<"object_number">>; Key =:= <<"object.object_number">> ->
    Acc#{
        <<"dcterms:identifier">> => Value
    };
map_property(<<"creator">>, Value, Acc) ->
    Acc#{<<"rdfs:label">> => Value};
map_property(<<"production.date.start">> = Key, Value, Acc) when value =/= <<"?">> ->
    Acc2 = Acc#{
        Key => Value,
        <<"dcterms:date">> => Value
    },
    case year(Value) of
        undefined ->
            Acc2;
        Year ->
            Acc2#{<<"dbo:productionStartYear">> => Year}
    end;
map_property(<<"production.date.end">> = Key, Value, Acc) when value =/= <<"?">> ->
    Acc2 = Acc#{
        Key => Value,
        <<"dcterms:date">> => Value
    },
    case year(Value) of
        undefined ->
            Acc2;
        Year ->
            Acc2#{<<"dbo:productionEndYear">> => Year}
    end;
map_property(<<"reproduction.creator">>, Value, Acc) ->
    Acc#{<<"dcterms:creator">> => Value};
map_property(<<"reproduction.reference">>, Value, Acc) ->
    Acc#{<<"reference">> => Value};
map_property(Key, Values, Acc) when Key =:= <<"Dimension">>; Key =:= <<"dimension">> ->
    lists:foldl(
        fun map_dimension/2,
        Acc,
        to_list(Values)
    );
map_property(<<"technique">>, Value, Acc) ->
    Acc#{<<"dbpedia-owl:technique">> => to_labelled_list(Value)};
%% @doc See e.g. http://wikidata.dbpedia.org/page/Q1248830
map_property(<<"material">>, Values, Acc) when is_list(Values) ->
    %% List of materials as single value
    %% @doc See e.g. http://wikidata.dbpedia.org/page/Q1248830
    Acc#{<<"dbpedia-owl:constructionMaterial">> => to_labelled_list(Values)};
map_property(<<"material">>, Value, Acc) ->
    %% Single material as value
    Acc#{<<"rdfs:label">> => Value};
map_property(<<"rights">>, Value, Acc) ->
    Acc2 = Acc#{<<"rights">> => Value},
    case m_creative_commons:url_for(Value) of
        undefined ->
            Acc2;
        Url ->
            Acc2#{<<"dcterms:license">> => Url}
    end;
map_property(Key, [Value], Acc) ->
    map_property(Key, Value, Acc);
map_property(Key, Value, Acc) ->
    Acc#{Key => Value}.

map_dimension(#{<<"dimension.type">> := Type, <<"dimension.unit">> := Unit, <<"dimension.value">> := Value}, Acc) ->
    Acc#{map_dimension_type(Type) => #{
        <<"rdf:type">> => <<"schema:QuantitativeValue">>,
        <<"schema:value">> => Value,
        <<"schema:unitCode">> => map_dimension_unit(Unit),
        <<"schema:unitText">> => Unit
    }}.

%% @doc Map dimension unit to UN/CEFACT Common Codes for Units of Measurement
map_dimension_unit(<<"cm">>) ->
    <<"CMT">>;<commit_msg>[adlib_elasticsearch] Make dimension mapping more fault-tolerant<commit_after>%% @doc Default
-module(ginger_adlib_elasticsearch_mapping).

-export([
    map/1,
    map_property/3,
    year/1,
    to_list/1,
    to_labelled_list/1
]).

-include_lib("zotonic.hrl").

-callback map_property(Property :: binary(), Value :: binary(), Acc :: map()) -> NewAcc :: map().

map(Record) ->
    Record.

map_property(Key, [#{<<"value">> := Value}], Acc) ->
    %% Flatten Adlib's @lang/value xmltype=grouped structure.
    map_property(Key, Value, Acc);
map_property(Key, #{<<"value">> := Value}, Acc) ->
    %% Flatten Adlib's @lang/value xmltype=grouped structure.
    map_property(Key, Value, Acc);
map_property(Key, Value, Acc) when Key =:= <<"object_number">>; Key =:= <<"object.object_number">> ->
    Acc#{
        <<"dcterms:identifier">> => Value
    };
map_property(<<"creator">>, Value, Acc) ->
    Acc#{<<"rdfs:label">> => Value};
map_property(<<"production.date.start">> = Key, Value, Acc) when value =/= <<"?">> ->
    Acc2 = Acc#{
        Key => Value,
        <<"dcterms:date">> => Value
    },
    case year(Value) of
        undefined ->
            Acc2;
        Year ->
            Acc2#{<<"dbo:productionStartYear">> => Year}
    end;
map_property(<<"production.date.end">> = Key, Value, Acc) when value =/= <<"?">> ->
    Acc2 = Acc#{
        Key => Value,
        <<"dcterms:date">> => Value
    },
    case year(Value) of
        undefined ->
            Acc2;
        Year ->
            Acc2#{<<"dbo:productionEndYear">> => Year}
    end;
map_property(<<"reproduction.creator">>, Value, Acc) ->
    Acc#{<<"dcterms:creator">> => Value};
map_property(<<"reproduction.reference">>, Value, Acc) ->
    Acc#{<<"reference">> => Value};
map_property(Key, Values, Acc) when Key =:= <<"Dimension">>; Key =:= <<"dimension">> ->
    lists:foldl(
        fun map_dimension/2,
        Acc,
        to_list(Values)
    );
map_property(<<"technique">>, Value, Acc) ->
    Acc#{<<"dbpedia-owl:technique">> => to_labelled_list(Value)};
%% @doc See e.g. http://wikidata.dbpedia.org/page/Q1248830
map_property(<<"material">>, Values, Acc) when is_list(Values) ->
    %% List of materials as single value
    %% @doc See e.g. http://wikidata.dbpedia.org/page/Q1248830
    Acc#{<<"dbpedia-owl:constructionMaterial">> => to_labelled_list(Values)};
map_property(<<"material">>, Value, Acc) ->
    %% Single material as value
    Acc#{<<"rdfs:label">> => Value};
map_property(<<"rights">>, Value, Acc) ->
    Acc2 = Acc#{<<"rights">> => Value},
    case m_creative_commons:url_for(Value) of
        undefined ->
            Acc2;
        Url ->
            Acc2#{<<"dcterms:license">> => Url}
    end;
map_property(<<"dimension.unit">>, Value, Acc) ->
    Acc#{<<"schema:unitCode">> => map_dimension_unit(Value),
        <<"schema:unitText">> => Value
    };
map_property(Key, [Value], Acc) ->
    map_property(Key, Value, Acc);
map_property(Key, Value, Acc) ->
    Acc#{Key => Value}.

map_dimension(#{<<"dimension.type">> := Type, <<"dimension.value">> := Value}, Acc) ->
    Acc#{map_dimension_type(Type) => #{
        <<"rdf:type">> => <<"schema:QuantitativeValue">>,
        <<"schema:value">> => Value
    }};
map_dimension(_DimensionWithoutVolumeOrType, Acc) ->
    Acc.

%% @doc Map dimension unit to UN/CEFACT Common Codes for Units of Measurement
map_dimension_unit(<<"cm">>) ->
    <<"CMT">>;
{'fraction_non_alphanumeric': 0.21074007220216606, 'fraction_numerical': 0.008724428399518652, 'mean_word_length': 3.3429131286740694, 'pattern_counts': {'":': 0, '<': 163, '<?xml version=': 0, '>': 257, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '834222', 'n_tokens_mistral': 2383, 'n_tokens_neox': 2330, 'n_words': 444}