From e188bec08be98c5e16de5352d8b834a74995bcaa Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Mon, 22 Jul 2024 18:04:34 -0300 Subject: [PATCH 01/15] #10600 add OSD schema --- lib/media/ver10/profile/osd.ex | 156 +++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 lib/media/ver10/profile/osd.ex diff --git a/lib/media/ver10/profile/osd.ex b/lib/media/ver10/profile/osd.ex new file mode 100644 index 0000000..0c4d4b1 --- /dev/null +++ b/lib/media/ver10/profile/osd.ex @@ -0,0 +1,156 @@ +defmodule Onvif.Media.Ver10.Profile.OSD do + @moduledoc """ + OSD (On-Screen Display) specification. + """ + + use Ecto.Schema + import Ecto.Changeset + import SweetXml + + @primary_key false + @derive Jason.Encoder + @required [:token, :video_source_configuration_token, :type] + @optional [] + + embedded_schema do + field(:token, :string) + field(:video_source_configuration_token, :string) + field(:type, Ecto.Enum, values: [text: "Text", image: "Image", extended: "Extended"]) + + embeds_one :position, Position, primary_key: false, on_replace: :update do + @derive Jason.Encoder + field(:type, Ecto.Enum, values: [upper_left: "UpperLeft", upper_right: "UpperRight", lower_left: "LowerLeft", lower_right: "LowerRight", custom: "Custom"]) + field(:pos, :integer) + end + + embeds_one :text_string, TextString, primary_key: false, on_replace: :update do + @derive Jason.Encoder + field(:is_persistent_text, :boolean) + field(:type, Ecto.Enum, values: [plain: "Plain", date: "Date", time: "Time", date_and_time: "DateAndTime"]) + field(:date_format, :string) + field(:time_format, :string) + field(:font_size, :integer) + embeds_one :font_color, FontColor, primary_key: false, on_replace: :update do + @derive Jason.Encoder + field(:transparent, :boolean) + field(:color, :string) + end + embeds_one :background_color, BackgroundColor, primary_key: false, on_replace: :update do + @derive Jason.Encoder + field(:transparent, :boolean) + field(:color, :string) + end + field(:plain_text, :string) + end + + embeds_one :image, Image, primary_key: false, on_replace: :update do + @derive Jason.Encoder + field(:image_path, :string) + end + end + + def parse(nil), do: nil + def parse([]), do: nil + def parse(doc) do + xmap( + doc, + token: ~x"./tt:Token/text()"so, + video_source_configuration_token: ~x"./tt:VideoSourceConfigurationToken/text()"so, + type: ~x"./tt:Type/text()"so, + position: ~x"./tt:Position"eo |> transform_by(&parse_position/1), + text_string: ~x"./tt:TextString"eo |> transform_by(&parse_text_string/1), + image: ~x"./tt:Image"eo |> transform_by(&parse_image/1) + ) + end + + def parse_position([]), do: nil + def parse_position(nil), do: nil + def parse_position(doc) do + xmap( + doc, + type: ~x"./tt:Type/text()"so, + pos: ~x"./tt:Pos/text()"io + ) + end + + def parse_text_string([]), do: nil + def parse_text_string(nil), do: nil + def parse_text_string(doc) do + xmap( + doc, + is_persistent_text: ~x"./tt:IsPersistentText/text()"so, + type: ~x"./tt:Type/text()"so, + date_format: ~x"./tt:DateFormat/text()"so, + time_format: ~x"./tt:TimeFormat/text()"so, + font_size: ~x"./tt:FontSize/text()"io, + font_color: ~x"./tt:FontColor"eo |> transform_by(&parse_color/1), + background_color: ~x"./tt:BackgroundColor"eo |> transform_by(&parse_color/1), + plain_text: ~x"./tt:PlainText/text()"so + ) + end + + def parse_color([]), do: nil + def parse_color(nil), do: nil + def parse_color(doc) do + xmap( + doc, + transparent: ~x"./tt:Transparent/text()"so, + color: ~x"./tt:Color/text()"so + ) + end + + def parse_image([]), do: nil + def parse_image(nil), do: nil + def parse_image(doc) do + xmap( + doc, + image_path: ~x"./tt:ImagePath/text()"so + ) + end + + def to_struct(parsed) do + %__MODULE__{} + |> changeset(parsed) + |> apply_action(:validate) + end + + @spec to_json(%Onvif.Media.Ver10.Profile.OSD{}) :: + {:error, + %{ + :__exception__ => any, + :__struct__ => Jason.EncodeError | Protocol.UndefinedError, + optional(atom) => any + }} + | {:ok, binary} + def to_json(%__MODULE__{} = schema) do + Jason.encode(schema) + end + + def changeset(module, attrs) do + module + |> cast(attrs, @required ++ @optional) + |> validate_required(@required) + |> cast_embed(:position, with: &position_changeset/2) + |> cast_embed(:text_string, with: &text_string_changeset/2) + |> cast_embed(:image, with: &image_changeset/2) + end + + def position_changeset(module, attrs) do + cast(module, attrs, [:type, :pos]) + end + + def text_string_changeset(module, attrs) do + cast(module, attrs, [:is_persistent_text, :type, :date_format, :time_format, :font_size, :plain_text]) + |> cast_embed(:font_color, with: &color_changeset/2) + |> cast_embed(:background_color, with: &color_changeset/2) + end + + def color_changeset(module, attrs) do + cast(module, attrs, [:transparent, :color]) + end + + def image_changeset(module, attrs) do + cast(module, attrs, [:image_path]) + end + +end From 184acf7e8fd7f9753afe0f6dc292bcd2db43697f Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Mon, 22 Jul 2024 20:29:16 -0300 Subject: [PATCH 02/15] #10600 fix path for osd schema --- lib/media/ver10/{profile => }/osd.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename lib/media/ver10/{profile => }/osd.ex (99%) diff --git a/lib/media/ver10/profile/osd.ex b/lib/media/ver10/osd.ex similarity index 99% rename from lib/media/ver10/profile/osd.ex rename to lib/media/ver10/osd.ex index 0c4d4b1..e5e5eba 100644 --- a/lib/media/ver10/profile/osd.ex +++ b/lib/media/ver10/osd.ex @@ -1,4 +1,4 @@ -defmodule Onvif.Media.Ver10.Profile.OSD do +defmodule Onvif.Media.Ver10.OSD do @moduledoc """ OSD (On-Screen Display) specification. """ From 4fa6c62f6d713a44b6b8efff095688d39bb1a92e Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Mon, 22 Jul 2024 20:50:17 -0300 Subject: [PATCH 03/15] #10600 fix schema+add initial getOSD --- lib/media/ver10/get_osd.ex | 0 lib/media/ver10/osd.ex | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 lib/media/ver10/get_osd.ex diff --git a/lib/media/ver10/get_osd.ex b/lib/media/ver10/get_osd.ex new file mode 100644 index 0000000..e69de29 diff --git a/lib/media/ver10/osd.ex b/lib/media/ver10/osd.ex index e5e5eba..9dd7914 100644 --- a/lib/media/ver10/osd.ex +++ b/lib/media/ver10/osd.ex @@ -27,8 +27,8 @@ defmodule Onvif.Media.Ver10.OSD do @derive Jason.Encoder field(:is_persistent_text, :boolean) field(:type, Ecto.Enum, values: [plain: "Plain", date: "Date", time: "Time", date_and_time: "DateAndTime"]) - field(:date_format, :string) - field(:time_format, :string) + field(:date_format, Ecto.Enum, values: ["M/d/yyyy": "M/d/yyyy", "MM/dd/yyyy": "MM/dd/yyyy", "yyyy-MM-dd": "yyyy-MM-dd", "dd/MM/yyyy": "dd/MM/yyyy", "yyyy/MM/dd": "yyyy/MM/dd", "dd-MM-yyyy": "dd-MM-yyyy", "yyyy-MM-dd": "yyyy-MM-dd", "dd.MM.yyyy": "dd.MM.yyyy", "yyyy.MM.dd": "yyyy.MM.dd", "dd.MM.yyyy": "dd.MM.yyyy", "yyyy.MM.dd": "yyyy.MM.dd", "dd-MM-yyyy": "dd-MM-yyyy", "yyyy-MM-dd": "yyyy-MM-dd", "dd/MM/yyyy": "dd/MM/yyyy", "yyyy/MM/dd": "yyyy/MM/dd", "MM/dd/yyyy": "MM/dd/yyyy", "M/d/yyyy": "M/d/yyyy"]) + field(:time_format, Ecto.Enum, values: ["h:mm:ss tt": "h:mm:ss tt", "hh:mm:ss tt": "hh:mm:ss tt", "H:mm:ss": "H:mm:ss", "HH:mm:ss": "HH:mm:ss", "h:mm tt": "h:mm tt", "hh:mm tt": "hh:mm tt", "H:mm": "H:mm", "HH:mm": "HH:mm"]) field(:font_size, :integer) embeds_one :font_color, FontColor, primary_key: false, on_replace: :update do @derive Jason.Encoder From d16964a6ff053f5c85f2da4d682c63f6f294686a Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Mon, 22 Jul 2024 21:04:07 -0300 Subject: [PATCH 04/15] #10600 add token to getOSD --- lib/media/ver10/get_osd.ex | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/media/ver10/get_osd.ex b/lib/media/ver10/get_osd.ex index e69de29..b3a098f 100644 --- a/lib/media/ver10/get_osd.ex +++ b/lib/media/ver10/get_osd.ex @@ -0,0 +1,36 @@ +defmodule Onvif.Media.Ver10.GetOSD do + import SweetXml + import XmlBuilder + + alias Onvif.Device + alias Onvif.Media.Ver10.OSD + + @spec soap_action :: String.t() + def soap_action, do: "http://www.onvif.org/ver10/media/wsdl/GetOSD" + + @spec request(Device.t(), list) :: {:ok, any} | {:error, map()} + def request(device, args), + do: Onvif.Media.Ver10.Media.request(device, args, __MODULE__) + + def request_body(token) do + element(:"s:Body", [ + element(:"trt:GetOSD", [ + element(:"tt:OSDToken", token) + ]) + ]) + end + + @spec response(any) :: {:error, Ecto.Changeset.t()} | {:ok, struct()} + def response(xml_response_body) do + xml_response_body + |> parse(namespace_conformant: true, quiet: true) + |> xpath( + ~x"//s:Envelope/s:Body/trt:GetVideoEncoderConfigurationResponse/trt:Configuration"e + |> add_namespace("s", "http://www.w3.org/2003/05/soap-envelope") + |> add_namespace("trt", "http://www.onvif.org/ver10/media/wsdl") + |> add_namespace("tt", "http://www.onvif.org/ver10/schema") + ) + |> OSD.parse() + |> OSD.to_struct() + end +end From 4da7a5761f5a53c938de7606152cbb9fd42ec7eb Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Tue, 23 Jul 2024 17:18:20 -0300 Subject: [PATCH 05/15] #10600 add getOSDs to grab tokens --- lib/media/ver10/get_osd.ex | 2 +- lib/media/ver10/get_osds.ex | 42 +++++++++++++++++++++++++++++++++++++ lib/media/ver10/osd.ex | 18 ++++++++++++---- 3 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 lib/media/ver10/get_osds.ex diff --git a/lib/media/ver10/get_osd.ex b/lib/media/ver10/get_osd.ex index b3a098f..c4f1950 100644 --- a/lib/media/ver10/get_osd.ex +++ b/lib/media/ver10/get_osd.ex @@ -25,7 +25,7 @@ defmodule Onvif.Media.Ver10.GetOSD do xml_response_body |> parse(namespace_conformant: true, quiet: true) |> xpath( - ~x"//s:Envelope/s:Body/trt:GetVideoEncoderConfigurationResponse/trt:Configuration"e + ~x"//s:Envelope/s:Body/trt:GetOSDResponse/trt:OSD"e |> add_namespace("s", "http://www.w3.org/2003/05/soap-envelope") |> add_namespace("trt", "http://www.onvif.org/ver10/media/wsdl") |> add_namespace("tt", "http://www.onvif.org/ver10/schema") diff --git a/lib/media/ver10/get_osds.ex b/lib/media/ver10/get_osds.ex new file mode 100644 index 0000000..643c5cf --- /dev/null +++ b/lib/media/ver10/get_osds.ex @@ -0,0 +1,42 @@ +defmodule Onvif.Media.Ver10.GetOSDs do + import SweetXml + import XmlBuilder + require Logger + + alias Onvif.Device + alias Onvif.Media.Ver10.OSD + + def soap_action, do: "http://www.onvif.org/ver10/media/wsdl/GetOSDs" + + def request(device), + do: Onvif.Media.Ver10.Media.request(device, __MODULE__) + + def request_body() do + element(:"s:Body", [ + element(:"trt:GetOSDs") + ]) + end + + @spec response(any) :: {:error, Ecto.Changeset.t()} | {:ok, struct()} + def response(xml_response_body) do + xml_response_body + |> parse(namespace_conformant: true, quiet: true) + |> xpath( + ~x"//s:Envelope/s:Body/trt:GetOSDsResponse/trt:OSDs"el + |> add_namespace("s", "http://www.w3.org/2003/05/soap-envelope") + |> add_namespace("trt", "http://www.onvif.org/ver10/media/wsdl") + |> add_namespace("tt", "http://www.onvif.org/ver10/schema") + ) + |> Enum.map(&OSD.parse/1) + |> Enum.reduce([], fn raw_service, acc -> + case OSD.to_struct(raw_service) do + {:ok, service} -> + [service | acc] + + {:error, changeset} -> + Logger.error("Discarding invalid service: #{inspect(changeset)}") + acc + end + end) + end +end diff --git a/lib/media/ver10/osd.ex b/lib/media/ver10/osd.ex index 9dd7914..c3058c9 100644 --- a/lib/media/ver10/osd.ex +++ b/lib/media/ver10/osd.ex @@ -27,8 +27,18 @@ defmodule Onvif.Media.Ver10.OSD do @derive Jason.Encoder field(:is_persistent_text, :boolean) field(:type, Ecto.Enum, values: [plain: "Plain", date: "Date", time: "Time", date_and_time: "DateAndTime"]) - field(:date_format, Ecto.Enum, values: ["M/d/yyyy": "M/d/yyyy", "MM/dd/yyyy": "MM/dd/yyyy", "yyyy-MM-dd": "yyyy-MM-dd", "dd/MM/yyyy": "dd/MM/yyyy", "yyyy/MM/dd": "yyyy/MM/dd", "dd-MM-yyyy": "dd-MM-yyyy", "yyyy-MM-dd": "yyyy-MM-dd", "dd.MM.yyyy": "dd.MM.yyyy", "yyyy.MM.dd": "yyyy.MM.dd", "dd.MM.yyyy": "dd.MM.yyyy", "yyyy.MM.dd": "yyyy.MM.dd", "dd-MM-yyyy": "dd-MM-yyyy", "yyyy-MM-dd": "yyyy-MM-dd", "dd/MM/yyyy": "dd/MM/yyyy", "yyyy/MM/dd": "yyyy/MM/dd", "MM/dd/yyyy": "MM/dd/yyyy", "M/d/yyyy": "M/d/yyyy"]) - field(:time_format, Ecto.Enum, values: ["h:mm:ss tt": "h:mm:ss tt", "hh:mm:ss tt": "hh:mm:ss tt", "H:mm:ss": "H:mm:ss", "HH:mm:ss": "HH:mm:ss", "h:mm tt": "h:mm tt", "hh:mm tt": "hh:mm tt", "H:mm": "H:mm", "HH:mm": "HH:mm"]) + field(:date_format, Ecto.Enum, values: ["M/d/yyyy": "M/d/yyyy", + "MM/dd/yyyy": "MM/dd/yyyy", + "dd/MM/yyyy": "dd/MM/yyyy", + "yyyy/MM/dd": "yyyy/MM/dd", + "yyyy-MM-dd": "yyyy-MM-dd", + "dddd, MMMM dd, yyyy ": "dddd, MMMM dd, yyyy ", + "MMMM dd, yyyy ": "MMMM dd, yyyy ", + "dd MMMM, yyyy": "dd MMMM, yyyy"]) + field(:time_format, Ecto.Enum, values: ["h:mm:ss tt": "h:mm:ss tt", + "hh:mm:ss tt": "hh:mm:ss tt", + "H:mm:ss": "H:mm:ss", + "HH:mm:ss": "HH:mm:ss"]) field(:font_size, :integer) embeds_one :font_color, FontColor, primary_key: false, on_replace: :update do @derive Jason.Encoder @@ -54,7 +64,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse(doc) do xmap( doc, - token: ~x"./tt:Token/text()"so, + token: ~x"//@token"so, video_source_configuration_token: ~x"./tt:VideoSourceConfigurationToken/text()"so, type: ~x"./tt:Type/text()"so, position: ~x"./tt:Position"eo |> transform_by(&parse_position/1), @@ -114,7 +124,7 @@ defmodule Onvif.Media.Ver10.OSD do |> apply_action(:validate) end - @spec to_json(%Onvif.Media.Ver10.Profile.OSD{}) :: + @spec to_json(%Onvif.Media.Ver10.OSD{}) :: {:error, %{ :__exception__ => any, From fe3f51bccd46ddae691d5273e4b526a1fa910e1a Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Tue, 23 Jul 2024 17:42:46 -0300 Subject: [PATCH 06/15] #10600 improve schema parsing --- lib/media/ver10/osd.ex | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/media/ver10/osd.ex b/lib/media/ver10/osd.ex index c3058c9..2991a21 100644 --- a/lib/media/ver10/osd.ex +++ b/lib/media/ver10/osd.ex @@ -20,7 +20,7 @@ defmodule Onvif.Media.Ver10.OSD do embeds_one :position, Position, primary_key: false, on_replace: :update do @derive Jason.Encoder field(:type, Ecto.Enum, values: [upper_left: "UpperLeft", upper_right: "UpperRight", lower_left: "LowerLeft", lower_right: "LowerRight", custom: "Custom"]) - field(:pos, :integer) + field(:pos, :map) end embeds_one :text_string, TextString, primary_key: false, on_replace: :update do @@ -43,7 +43,7 @@ defmodule Onvif.Media.Ver10.OSD do embeds_one :font_color, FontColor, primary_key: false, on_replace: :update do @derive Jason.Encoder field(:transparent, :boolean) - field(:color, :string) + field(:color, :map) end embeds_one :background_color, BackgroundColor, primary_key: false, on_replace: :update do @derive Jason.Encoder @@ -79,10 +79,19 @@ defmodule Onvif.Media.Ver10.OSD do xmap( doc, type: ~x"./tt:Type/text()"so, - pos: ~x"./tt:Pos/text()"io + pos: ~x"./tt:Pos"eo |> transform_by(&parse_pos/1) ) end + def parse_pos([]), do: nil + def parse_pos(nil), do: nil + def parse_pos(doc) do + %{ + x: doc |> xpath(~x"./@x"s) |> String.to_float(), + y: doc |> xpath(~x"./@y"s) |> String.to_float() + } + end + def parse_text_string([]), do: nil def parse_text_string(nil), do: nil def parse_text_string(doc) do @@ -105,10 +114,21 @@ defmodule Onvif.Media.Ver10.OSD do xmap( doc, transparent: ~x"./tt:Transparent/text()"so, - color: ~x"./tt:Color/text()"so + color: ~x"./tt:Color"eo |> transform_by(&parse_inner_color/1) ) end + def parse_inner_color([]), do: nil + def parse_inner_color(nil), do: nil + def parse_inner_color(doc) do + %{ + x: doc |> xpath(~x"./@X"s) |> String.to_float(), + y: doc |> xpath(~x"./@Y"s) |> String.to_float(), + z: doc |> xpath(~x"./@Z"s) |> String.to_float(), + colorspace: doc |> xpath(~x"./@Colorspace"s) + } + end + def parse_image([]), do: nil def parse_image(nil), do: nil def parse_image(doc) do From 7d39e0692dfbbb9fe16b560ef176b175430c4d45 Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Tue, 23 Jul 2024 17:48:18 -0300 Subject: [PATCH 07/15] #10600 improve readability --- lib/media/ver10/osd.ex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/media/ver10/osd.ex b/lib/media/ver10/osd.ex index 2991a21..a9b9efd 100644 --- a/lib/media/ver10/osd.ex +++ b/lib/media/ver10/osd.ex @@ -19,7 +19,11 @@ defmodule Onvif.Media.Ver10.OSD do embeds_one :position, Position, primary_key: false, on_replace: :update do @derive Jason.Encoder - field(:type, Ecto.Enum, values: [upper_left: "UpperLeft", upper_right: "UpperRight", lower_left: "LowerLeft", lower_right: "LowerRight", custom: "Custom"]) + field(:type, Ecto.Enum, values: [upper_left: "UpperLeft", + upper_right: "UpperRight", + lower_left: "LowerLeft", + lower_right: "LowerRight", + custom: "Custom"]) field(:pos, :map) end From f6f73258bf0330480d9755ec0abe5d48a75b3b3d Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Tue, 23 Jul 2024 18:39:28 -0300 Subject: [PATCH 08/15] #10600 remove unused struct --- lib/media/ver10/get_osds.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/media/ver10/get_osds.ex b/lib/media/ver10/get_osds.ex index 643c5cf..c54f57f 100644 --- a/lib/media/ver10/get_osds.ex +++ b/lib/media/ver10/get_osds.ex @@ -3,7 +3,6 @@ defmodule Onvif.Media.Ver10.GetOSDs do import XmlBuilder require Logger - alias Onvif.Device alias Onvif.Media.Ver10.OSD def soap_action, do: "http://www.onvif.org/ver10/media/wsdl/GetOSDs" From 812516d4f88e722888660d4f4ffc9f6176e62783 Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Tue, 23 Jul 2024 18:41:07 -0300 Subject: [PATCH 09/15] #10600 add tests --- test/media/ver10/fixtures/get_osds_empty.xml | 21 +++++ .../ver10/fixtures/get_osds_response.xml | 84 +++++++++++++++++++ test/media/ver10/get_osds.exs | 70 ++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 test/media/ver10/fixtures/get_osds_empty.xml create mode 100644 test/media/ver10/fixtures/get_osds_response.xml create mode 100644 test/media/ver10/get_osds.exs diff --git a/test/media/ver10/fixtures/get_osds_empty.xml b/test/media/ver10/fixtures/get_osds_empty.xml new file mode 100644 index 0000000..e850696 --- /dev/null +++ b/test/media/ver10/fixtures/get_osds_empty.xml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/test/media/ver10/fixtures/get_osds_response.xml b/test/media/ver10/fixtures/get_osds_response.xml new file mode 100644 index 0000000..3938578 --- /dev/null +++ b/test/media/ver10/fixtures/get_osds_response.xml @@ -0,0 +1,84 @@ + + + + + + VideoSourceToken + Text + + Custom + + + + DateAndTime + MM/dd/yyyy + HH:mm:ss + 32 + + + + + false + + + + + VideoSourceToken + Text + + Custom + + + + Plain + 32 + + + + Camera 01 + + true + + + + + + \ No newline at end of file diff --git a/test/media/ver10/get_osds.exs b/test/media/ver10/get_osds.exs new file mode 100644 index 0000000..a40992e --- /dev/null +++ b/test/media/ver10/get_osds.exs @@ -0,0 +1,70 @@ +defmodule Onvif.Media.Ver10.GetOSDsTest do + use ExUnit.Case, async: true + + @moduletag capture_log: true + + describe "GetOSDs/1" do + test "should list 2 OSDs" do + xml_response = + File.read!( + "test/media/ver10/fixtures/get_osds_response.xml" + ) + + device = Onvif.Factory.device() + + Mimic.expect(Tesla, :request, fn _client, _opts -> + {:ok, %{status: 200, body: xml_response}} + end) + + osds = Onvif.Media.Ver10.GetOSDs.request(device) + + assert length(osds) == 2 + assert hd(osds) == %Onvif.Media.Ver10.OSD{ + image: nil, + position: %Onvif.Media.Ver10.OSD.Position{ + pos: %{x: 0.454545, y: -0.733333}, + type: :custom + }, + text_string: %Onvif.Media.Ver10.OSD.TextString{ + background_color: nil, + date_format: nil, + font_color: %Onvif.Media.Ver10.OSD.TextString.FontColor{ + color: %{ + colorspace: "http://www.onvif.org/ver10/colorspace/YCbCr", + x: 0.0, + y: 0.0, + z: 0.0 + }, + transparent: nil + }, + font_size: 32, + is_persistent_text: nil, + plain_text: "Camera 01", + time_format: nil, + type: :plain + }, + token: "OsdToken_100", + type: :text, + video_source_configuration_token: "VideoSourceToken" + } + end + + test "should have no OSD available" do + xml_response = + File.read!( + "test/media/ver10/fixtures/get_osds_empty.xml" + ) + + device = Onvif.Factory.device() + + Mimic.expect(Tesla, :request, fn _client, _opts -> + {:ok, %{status: 200, body: xml_response}} + end) + + osds = Onvif.Media.Ver10.GetOSDs.request(device) + + assert length(osds) == 0 + end + + end +end From 4209371df9011229e00aa1a2083431c71aacd066 Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Wed, 24 Jul 2024 13:12:00 -0300 Subject: [PATCH 10/15] #10600 mix format --- lib/media/ver10/get_osds.ex | 18 ++++----- lib/media/ver10/osd.ex | 75 +++++++++++++++++++++++++---------- test/media/ver10/get_osds.exs | 66 ++++++++++++++---------------- 3 files changed, 94 insertions(+), 65 deletions(-) diff --git a/lib/media/ver10/get_osds.ex b/lib/media/ver10/get_osds.ex index c54f57f..edf2634 100644 --- a/lib/media/ver10/get_osds.ex +++ b/lib/media/ver10/get_osds.ex @@ -27,15 +27,15 @@ defmodule Onvif.Media.Ver10.GetOSDs do |> add_namespace("tt", "http://www.onvif.org/ver10/schema") ) |> Enum.map(&OSD.parse/1) - |> Enum.reduce([], fn raw_service, acc -> - case OSD.to_struct(raw_service) do - {:ok, service} -> - [service | acc] + |> Enum.reduce([], fn raw_service, acc -> + case OSD.to_struct(raw_service) do + {:ok, service} -> + [service | acc] - {:error, changeset} -> - Logger.error("Discarding invalid service: #{inspect(changeset)}") - acc - end - end) + {:error, changeset} -> + Logger.error("Discarding invalid service: #{inspect(changeset)}") + acc + end + end) end end diff --git a/lib/media/ver10/osd.ex b/lib/media/ver10/osd.ex index a9b9efd..d01452f 100644 --- a/lib/media/ver10/osd.ex +++ b/lib/media/ver10/osd.ex @@ -19,41 +19,63 @@ defmodule Onvif.Media.Ver10.OSD do embeds_one :position, Position, primary_key: false, on_replace: :update do @derive Jason.Encoder - field(:type, Ecto.Enum, values: [upper_left: "UpperLeft", - upper_right: "UpperRight", - lower_left: "LowerLeft", - lower_right: "LowerRight", - custom: "Custom"]) + field(:type, Ecto.Enum, + values: [ + upper_left: "UpperLeft", + upper_right: "UpperRight", + lower_left: "LowerLeft", + lower_right: "LowerRight", + custom: "Custom" + ] + ) + field(:pos, :map) end embeds_one :text_string, TextString, primary_key: false, on_replace: :update do @derive Jason.Encoder field(:is_persistent_text, :boolean) - field(:type, Ecto.Enum, values: [plain: "Plain", date: "Date", time: "Time", date_and_time: "DateAndTime"]) - field(:date_format, Ecto.Enum, values: ["M/d/yyyy": "M/d/yyyy", - "MM/dd/yyyy": "MM/dd/yyyy", - "dd/MM/yyyy": "dd/MM/yyyy", - "yyyy/MM/dd": "yyyy/MM/dd", - "yyyy-MM-dd": "yyyy-MM-dd", - "dddd, MMMM dd, yyyy ": "dddd, MMMM dd, yyyy ", - "MMMM dd, yyyy ": "MMMM dd, yyyy ", - "dd MMMM, yyyy": "dd MMMM, yyyy"]) - field(:time_format, Ecto.Enum, values: ["h:mm:ss tt": "h:mm:ss tt", - "hh:mm:ss tt": "hh:mm:ss tt", - "H:mm:ss": "H:mm:ss", - "HH:mm:ss": "HH:mm:ss"]) + + field(:type, Ecto.Enum, + values: [plain: "Plain", date: "Date", time: "Time", date_and_time: "DateAndTime"] + ) + + field(:date_format, Ecto.Enum, + values: [ + "M/d/yyyy": "M/d/yyyy", + "MM/dd/yyyy": "MM/dd/yyyy", + "dd/MM/yyyy": "dd/MM/yyyy", + "yyyy/MM/dd": "yyyy/MM/dd", + "yyyy-MM-dd": "yyyy-MM-dd", + "dddd, MMMM dd, yyyy ": "dddd, MMMM dd, yyyy ", + "MMMM dd, yyyy ": "MMMM dd, yyyy ", + "dd MMMM, yyyy": "dd MMMM, yyyy" + ] + ) + + field(:time_format, Ecto.Enum, + values: [ + "h:mm:ss tt": "h:mm:ss tt", + "hh:mm:ss tt": "hh:mm:ss tt", + "H:mm:ss": "H:mm:ss", + "HH:mm:ss": "HH:mm:ss" + ] + ) + field(:font_size, :integer) + embeds_one :font_color, FontColor, primary_key: false, on_replace: :update do @derive Jason.Encoder field(:transparent, :boolean) field(:color, :map) end + embeds_one :background_color, BackgroundColor, primary_key: false, on_replace: :update do @derive Jason.Encoder field(:transparent, :boolean) field(:color, :string) end + field(:plain_text, :string) end @@ -65,6 +87,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse(nil), do: nil def parse([]), do: nil + def parse(doc) do xmap( doc, @@ -79,6 +102,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse_position([]), do: nil def parse_position(nil), do: nil + def parse_position(doc) do xmap( doc, @@ -89,6 +113,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse_pos([]), do: nil def parse_pos(nil), do: nil + def parse_pos(doc) do %{ x: doc |> xpath(~x"./@x"s) |> String.to_float(), @@ -98,6 +123,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse_text_string([]), do: nil def parse_text_string(nil), do: nil + def parse_text_string(doc) do xmap( doc, @@ -114,6 +140,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse_color([]), do: nil def parse_color(nil), do: nil + def parse_color(doc) do xmap( doc, @@ -124,6 +151,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse_inner_color([]), do: nil def parse_inner_color(nil), do: nil + def parse_inner_color(doc) do %{ x: doc |> xpath(~x"./@X"s) |> String.to_float(), @@ -135,6 +163,7 @@ defmodule Onvif.Media.Ver10.OSD do def parse_image([]), do: nil def parse_image(nil), do: nil + def parse_image(doc) do xmap( doc, @@ -174,7 +203,14 @@ defmodule Onvif.Media.Ver10.OSD do end def text_string_changeset(module, attrs) do - cast(module, attrs, [:is_persistent_text, :type, :date_format, :time_format, :font_size, :plain_text]) + cast(module, attrs, [ + :is_persistent_text, + :type, + :date_format, + :time_format, + :font_size, + :plain_text + ]) |> cast_embed(:font_color, with: &color_changeset/2) |> cast_embed(:background_color, with: &color_changeset/2) end @@ -186,5 +222,4 @@ defmodule Onvif.Media.Ver10.OSD do def image_changeset(module, attrs) do cast(module, attrs, [:image_path]) end - end diff --git a/test/media/ver10/get_osds.exs b/test/media/ver10/get_osds.exs index a40992e..5c8f5bc 100644 --- a/test/media/ver10/get_osds.exs +++ b/test/media/ver10/get_osds.exs @@ -5,10 +5,7 @@ defmodule Onvif.Media.Ver10.GetOSDsTest do describe "GetOSDs/1" do test "should list 2 OSDs" do - xml_response = - File.read!( - "test/media/ver10/fixtures/get_osds_response.xml" - ) + xml_response = File.read!("test/media/ver10/fixtures/get_osds_response.xml") device = Onvif.Factory.device() @@ -19,41 +16,39 @@ defmodule Onvif.Media.Ver10.GetOSDsTest do osds = Onvif.Media.Ver10.GetOSDs.request(device) assert length(osds) == 2 + assert hd(osds) == %Onvif.Media.Ver10.OSD{ - image: nil, - position: %Onvif.Media.Ver10.OSD.Position{ - pos: %{x: 0.454545, y: -0.733333}, - type: :custom - }, - text_string: %Onvif.Media.Ver10.OSD.TextString{ - background_color: nil, - date_format: nil, - font_color: %Onvif.Media.Ver10.OSD.TextString.FontColor{ - color: %{ - colorspace: "http://www.onvif.org/ver10/colorspace/YCbCr", - x: 0.0, - y: 0.0, - z: 0.0 - }, - transparent: nil - }, - font_size: 32, - is_persistent_text: nil, - plain_text: "Camera 01", - time_format: nil, - type: :plain - }, - token: "OsdToken_100", - type: :text, - video_source_configuration_token: "VideoSourceToken" - } + image: nil, + position: %Onvif.Media.Ver10.OSD.Position{ + pos: %{x: 0.454545, y: -0.733333}, + type: :custom + }, + text_string: %Onvif.Media.Ver10.OSD.TextString{ + background_color: nil, + date_format: nil, + font_color: %Onvif.Media.Ver10.OSD.TextString.FontColor{ + color: %{ + colorspace: "http://www.onvif.org/ver10/colorspace/YCbCr", + x: 0.0, + y: 0.0, + z: 0.0 + }, + transparent: nil + }, + font_size: 32, + is_persistent_text: nil, + plain_text: "Camera 01", + time_format: nil, + type: :plain + }, + token: "OsdToken_100", + type: :text, + video_source_configuration_token: "VideoSourceToken" + } end test "should have no OSD available" do - xml_response = - File.read!( - "test/media/ver10/fixtures/get_osds_empty.xml" - ) + xml_response = File.read!("test/media/ver10/fixtures/get_osds_empty.xml") device = Onvif.Factory.device() @@ -65,6 +60,5 @@ defmodule Onvif.Media.Ver10.GetOSDsTest do assert length(osds) == 0 end - end end From a633b61fe8c73033e99766091018d8311819f7c7 Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Wed, 24 Jul 2024 13:15:06 -0300 Subject: [PATCH 11/15] #10600 replace tab for 2 spaces --- test/media/ver10/fixtures/get_osds_empty.xml | 38 ++-- .../ver10/fixtures/get_osds_response.xml | 162 +++++++++--------- 2 files changed, 100 insertions(+), 100 deletions(-) diff --git a/test/media/ver10/fixtures/get_osds_empty.xml b/test/media/ver10/fixtures/get_osds_empty.xml index e850696..6886448 100644 --- a/test/media/ver10/fixtures/get_osds_empty.xml +++ b/test/media/ver10/fixtures/get_osds_empty.xml @@ -1,21 +1,21 @@ - - - + xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" + xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" + xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" + xmlns:ds="http://www.w3.org/2000/09/xmldsig#" + xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" + xmlns:wsa5="http://www.w3.org/2005/08/addressing" + xmlns:tt="http://www.onvif.org/ver10/schema" + xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" + xmlns:tns1="http://www.onvif.org/ver10/topics" + xmlns:tnsaxis="http://www.axis.com/2009/event/topics" + xmlns:tev="http://www.onvif.org/ver10/events/wsdl" + xmlns:trt="http://www.onvif.org/ver10/media/wsdl" + xmlns:ter="http://www.onvif.org/ver10/error"> + + + \ No newline at end of file diff --git a/test/media/ver10/fixtures/get_osds_response.xml b/test/media/ver10/fixtures/get_osds_response.xml index 3938578..e42eab6 100644 --- a/test/media/ver10/fixtures/get_osds_response.xml +++ b/test/media/ver10/fixtures/get_osds_response.xml @@ -1,84 +1,84 @@ - - - - VideoSourceToken - Text - - Custom - - - - DateAndTime - MM/dd/yyyy - HH:mm:ss - 32 - - - - - false - - - - - VideoSourceToken - Text - - Custom - - - - Plain - 32 - - - - Camera 01 - - true - - - - - + xmlns:env="http://www.w3.org/2003/05/soap-envelope" + xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:tt="http://www.onvif.org/ver10/schema" + xmlns:tds="http://www.onvif.org/ver10/device/wsdl" + xmlns:trt="http://www.onvif.org/ver10/media/wsdl" + xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" + xmlns:tev="http://www.onvif.org/ver10/events/wsdl" + xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" + xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" + xmlns:tst="http://www.onvif.org/ver10/storage/wsdl" + xmlns:ter="http://www.onvif.org/ver10/error" + xmlns:dn="http://www.onvif.org/ver10/network/wsdl" + xmlns:tns1="http://www.onvif.org/ver10/topics" + xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl" + xmlns:wsoap12="http://schemas.xmlsoap.org/wsdl/soap12" + xmlns:http="http://schemas.xmlsoap.org/wsdl/http" + xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" + xmlns:wsadis="http://schemas.xmlsoap.org/ws/2004/08/addressing" + xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" + xmlns:wsa="http://www.w3.org/2005/08/addressing" + xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" + xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" + xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2" + xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2" + xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" + xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" + xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" + xmlns:tse="http://www.onvif.org/ver10/search/wsdl" + xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" + xmlns:tnshik="http://www.hikvision.com/2011/event/topics" + xmlns:hikwsd="http://www.onvifext.com/onvif/ext/ver10/wsdl" + xmlns:hikxsd="http://www.onvifext.com/onvif/ext/ver10/schema" + xmlns:tas="http://www.onvif.org/ver10/advancedsecurity/wsdl" + xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" + xmlns:axt="http://www.onvif.org/ver20/analytics"> + + + + VideoSourceToken + Text + + Custom + + + + DateAndTime + MM/dd/yyyy + HH:mm:ss + 32 + + + + + false + + + + + VideoSourceToken + Text + + Custom + + + + Plain + 32 + + + + Camera 01 + + true + + + + + \ No newline at end of file From e7224398974372e5ec37a25c7f99405618fe2660 Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Wed, 24 Jul 2024 16:02:31 -0300 Subject: [PATCH 12/15] #10600 update variable name and function return --- lib/media/ver10/get_osds.ex | 38 ++++++++++++++++++----------------- test/media/ver10/get_osds.exs | 4 ++-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/media/ver10/get_osds.ex b/lib/media/ver10/get_osds.ex index edf2634..92bae45 100644 --- a/lib/media/ver10/get_osds.ex +++ b/lib/media/ver10/get_osds.ex @@ -18,24 +18,26 @@ defmodule Onvif.Media.Ver10.GetOSDs do @spec response(any) :: {:error, Ecto.Changeset.t()} | {:ok, struct()} def response(xml_response_body) do - xml_response_body - |> parse(namespace_conformant: true, quiet: true) - |> xpath( - ~x"//s:Envelope/s:Body/trt:GetOSDsResponse/trt:OSDs"el - |> add_namespace("s", "http://www.w3.org/2003/05/soap-envelope") - |> add_namespace("trt", "http://www.onvif.org/ver10/media/wsdl") - |> add_namespace("tt", "http://www.onvif.org/ver10/schema") - ) - |> Enum.map(&OSD.parse/1) - |> Enum.reduce([], fn raw_service, acc -> - case OSD.to_struct(raw_service) do - {:ok, service} -> - [service | acc] + response = + xml_response_body + |> parse(namespace_conformant: true, quiet: true) + |> xpath( + ~x"//s:Envelope/s:Body/trt:GetOSDsResponse/trt:OSDs"el + |> add_namespace("s", "http://www.w3.org/2003/05/soap-envelope") + |> add_namespace("trt", "http://www.onvif.org/ver10/media/wsdl") + |> add_namespace("tt", "http://www.onvif.org/ver10/schema") + ) + |> Enum.map(&OSD.parse/1) + |> Enum.reduce([], fn raw_osd, acc -> + case OSD.to_struct(raw_osd) do + {:ok, osd} -> + [osd | acc] - {:error, changeset} -> - Logger.error("Discarding invalid service: #{inspect(changeset)}") - acc - end - end) + {:error, changeset} -> + Logger.error("Discarding invalid service: #{inspect(changeset)}") + acc + end + end) + {:ok, response} end end diff --git a/test/media/ver10/get_osds.exs b/test/media/ver10/get_osds.exs index 5c8f5bc..06e68c0 100644 --- a/test/media/ver10/get_osds.exs +++ b/test/media/ver10/get_osds.exs @@ -13,7 +13,7 @@ defmodule Onvif.Media.Ver10.GetOSDsTest do {:ok, %{status: 200, body: xml_response}} end) - osds = Onvif.Media.Ver10.GetOSDs.request(device) + {:ok, osds} = Onvif.Media.Ver10.GetOSDs.request(device) assert length(osds) == 2 @@ -56,7 +56,7 @@ defmodule Onvif.Media.Ver10.GetOSDsTest do {:ok, %{status: 200, body: xml_response}} end) - osds = Onvif.Media.Ver10.GetOSDs.request(device) + {:ok, osds} = Onvif.Media.Ver10.GetOSDs.request(device) assert length(osds) == 0 end From 846c72ec2479f7ff46c2b3f6f4a64a865dd9455c Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Thu, 25 Jul 2024 11:18:26 -0300 Subject: [PATCH 13/15] #10600 fix for manufacturers with weird implementation --- lib/media/ver10/get_osds.ex | 13 ++++++++++++- lib/media/ver10/osd.ex | 10 +++++----- test/media/ver10/get_osds.exs | 8 ++++---- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/media/ver10/get_osds.ex b/lib/media/ver10/get_osds.ex index 92bae45..77e086e 100644 --- a/lib/media/ver10/get_osds.ex +++ b/lib/media/ver10/get_osds.ex @@ -8,7 +8,10 @@ defmodule Onvif.Media.Ver10.GetOSDs do def soap_action, do: "http://www.onvif.org/ver10/media/wsdl/GetOSDs" def request(device), - do: Onvif.Media.Ver10.Media.request(device, __MODULE__) + do: Onvif.Media.Ver10.Media.request(device, __MODULE__) + + def request(device, args), + do: Onvif.Media.Ver10.Media.request(device, args, __MODULE__) def request_body() do element(:"s:Body", [ @@ -16,6 +19,14 @@ defmodule Onvif.Media.Ver10.GetOSDs do ]) end + def request_body(video_source_token) do + element(:"s:Body", [ + element(:"trt:GetOSDs", [ + element(:"trt:ConfigurationToken", video_source_token) + ]) + ]) + end + @spec response(any) :: {:error, Ecto.Changeset.t()} | {:ok, struct()} def response(xml_response_body) do response = diff --git a/lib/media/ver10/osd.ex b/lib/media/ver10/osd.ex index d01452f..a05f02a 100644 --- a/lib/media/ver10/osd.ex +++ b/lib/media/ver10/osd.ex @@ -116,8 +116,8 @@ defmodule Onvif.Media.Ver10.OSD do def parse_pos(doc) do %{ - x: doc |> xpath(~x"./@x"s) |> String.to_float(), - y: doc |> xpath(~x"./@y"s) |> String.to_float() + x: doc |> xpath(~x"./@x"s), + y: doc |> xpath(~x"./@y"s) } end @@ -154,9 +154,9 @@ defmodule Onvif.Media.Ver10.OSD do def parse_inner_color(doc) do %{ - x: doc |> xpath(~x"./@X"s) |> String.to_float(), - y: doc |> xpath(~x"./@Y"s) |> String.to_float(), - z: doc |> xpath(~x"./@Z"s) |> String.to_float(), + x: doc |> xpath(~x"./@X"s), + y: doc |> xpath(~x"./@Y"s), + z: doc |> xpath(~x"./@Z"s), colorspace: doc |> xpath(~x"./@Colorspace"s) } end diff --git a/test/media/ver10/get_osds.exs b/test/media/ver10/get_osds.exs index 06e68c0..d830ea2 100644 --- a/test/media/ver10/get_osds.exs +++ b/test/media/ver10/get_osds.exs @@ -20,7 +20,7 @@ defmodule Onvif.Media.Ver10.GetOSDsTest do assert hd(osds) == %Onvif.Media.Ver10.OSD{ image: nil, position: %Onvif.Media.Ver10.OSD.Position{ - pos: %{x: 0.454545, y: -0.733333}, + pos: %{x: "0.454545", y: "-0.733333"}, type: :custom }, text_string: %Onvif.Media.Ver10.OSD.TextString{ @@ -29,9 +29,9 @@ defmodule Onvif.Media.Ver10.GetOSDsTest do font_color: %Onvif.Media.Ver10.OSD.TextString.FontColor{ color: %{ colorspace: "http://www.onvif.org/ver10/colorspace/YCbCr", - x: 0.0, - y: 0.0, - z: 0.0 + x: "0.000000", + y: "0.000000", + z: "0.000000" }, transparent: nil }, From a133692aad361d644d73cb86c3e310ffb282bdfb Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Thu, 25 Jul 2024 11:19:04 -0300 Subject: [PATCH 14/15] #10600 mix format --- lib/media/ver10/get_osds.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/media/ver10/get_osds.ex b/lib/media/ver10/get_osds.ex index 77e086e..1de9016 100644 --- a/lib/media/ver10/get_osds.ex +++ b/lib/media/ver10/get_osds.ex @@ -8,7 +8,7 @@ defmodule Onvif.Media.Ver10.GetOSDs do def soap_action, do: "http://www.onvif.org/ver10/media/wsdl/GetOSDs" def request(device), - do: Onvif.Media.Ver10.Media.request(device, __MODULE__) + do: Onvif.Media.Ver10.Media.request(device, __MODULE__) def request(device, args), do: Onvif.Media.Ver10.Media.request(device, args, __MODULE__) @@ -49,6 +49,7 @@ defmodule Onvif.Media.Ver10.GetOSDs do acc end end) + {:ok, response} end end From 0d1c7ac36bc374000636db2eba6c0229078b92cb Mon Sep 17 00:00:00 2001 From: Paolo Oliveira Date: Thu, 25 Jul 2024 14:22:34 -0300 Subject: [PATCH 15/15] #10600 improve validation for date and time --- lib/media/ver10/osd.ex | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/lib/media/ver10/osd.ex b/lib/media/ver10/osd.ex index a05f02a..cb08e45 100644 --- a/lib/media/ver10/osd.ex +++ b/lib/media/ver10/osd.ex @@ -40,28 +40,8 @@ defmodule Onvif.Media.Ver10.OSD do values: [plain: "Plain", date: "Date", time: "Time", date_and_time: "DateAndTime"] ) - field(:date_format, Ecto.Enum, - values: [ - "M/d/yyyy": "M/d/yyyy", - "MM/dd/yyyy": "MM/dd/yyyy", - "dd/MM/yyyy": "dd/MM/yyyy", - "yyyy/MM/dd": "yyyy/MM/dd", - "yyyy-MM-dd": "yyyy-MM-dd", - "dddd, MMMM dd, yyyy ": "dddd, MMMM dd, yyyy ", - "MMMM dd, yyyy ": "MMMM dd, yyyy ", - "dd MMMM, yyyy": "dd MMMM, yyyy" - ] - ) - - field(:time_format, Ecto.Enum, - values: [ - "h:mm:ss tt": "h:mm:ss tt", - "hh:mm:ss tt": "hh:mm:ss tt", - "H:mm:ss": "H:mm:ss", - "HH:mm:ss": "HH:mm:ss" - ] - ) - + field(:date_format, :string) + field(:time_format, :string) field(:font_size, :integer) embeds_one :font_color, FontColor, primary_key: false, on_replace: :update do @@ -213,6 +193,8 @@ defmodule Onvif.Media.Ver10.OSD do ]) |> cast_embed(:font_color, with: &color_changeset/2) |> cast_embed(:background_color, with: &color_changeset/2) + |> validate_inclusion(:date_format, ["M/d/yyyy", "MM/dd/yyyy", "dd/MM/yyyy", "yyyy/MM/dd", "yyyy-MM-dd", "dddd, MMMM dd, yyyy", "MMMM dd, yyyy", "dd MMMM, yyyy"]) + |> validate_inclusion(:time_format, ["h:mm:ss tt", "hh:mm:ss tt", "H:mm:ss", "HH:mm:ss"]) end def color_changeset(module, attrs) do