-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Onvif.Recording.CreateRecording * rename recording schema
- Loading branch information
Showing
4 changed files
with
327 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
defmodule Onvif.Recording.CreateRecording do | ||
import SweetXml | ||
import XmlBuilder | ||
require Logger | ||
|
||
def soap_action, do: "http://www.onvif.org/ver10/recording/wsdl/CreateRecording" | ||
|
||
def request(device, args) do | ||
Onvif.Recording.request(device, args, __MODULE__) | ||
end | ||
|
||
def request_body(config: %Onvif.Recording.Recording.Configuration{} = config) do | ||
element(:"s:Body", [ | ||
element(:"trc:CreateRecording", [ | ||
element(:"trc:RecordingConfiguration", [ | ||
element(:"tt:Source", [ | ||
gen_source_id(config.source.source_id), | ||
gen_name(config.source.name), | ||
gen_location(config.source.location), | ||
gen_description(config.source.description), | ||
gen_address(config.source.address) | ||
]), | ||
gen_content(config.content), | ||
gen_maximum_retention_time(config.maximum_retention_time) | ||
]) | ||
]) | ||
]) | ||
end | ||
|
||
def gen_source_id(nil), do: [] | ||
def gen_source_id(""), do: [] | ||
def gen_source_id(source_id), do: element(:"tt:SourceId", source_id) | ||
|
||
def gen_name(nil), do: [] | ||
def gen_name(""), do: [] | ||
def gen_name(name), do: element(:"tt:Name", name) | ||
|
||
def gen_location(nil), do: [] | ||
def gen_location(""), do: [] | ||
def gen_location(location), do: element(:"tt:Location", location) | ||
|
||
def gen_description(nil), do: [] | ||
def gen_description(""), do: [] | ||
def gen_description(description), do: element(:"tt:Description", description) | ||
|
||
def gen_address(nil), do: [] | ||
def gen_address(""), do: [] | ||
def gen_address(address), do: element(:"tt:Address", address) | ||
|
||
def gen_content(nil), do: [] | ||
def gen_content(""), do: [] | ||
def gen_content(content), do: element(:"tt:Content", content) | ||
|
||
def gen_maximum_retention_time(nil), do: [] | ||
def gen_maximum_retention_time(""), do: [] | ||
def gen_maximum_retention_time(maximum_retention_time), do: element(:"tt:MaximumRetentionTime", maximum_retention_time) | ||
|
||
|
||
def response(xml_response_body) do | ||
recording_token = | ||
xml_response_body | ||
|> parse(namespace_conformant: true, quiet: true) | ||
|> xpath( | ||
~x"//s:Envelope/s:Body/trc:CreateRecordingResponse/trc:RecordingToken/text()"s | ||
|> add_namespace("s", "http://www.w3.org/2003/05/soap-envelope") | ||
|> add_namespace("trc", "http://www.onvif.org/ver10/recording/wsdl") | ||
) | ||
|
||
{:ok, recording_token} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
defmodule Onvif.Recording.Recording do | ||
@moduledoc """ | ||
Onvif.Recording.Recordings schema. | ||
""" | ||
|
||
use Ecto.Schema | ||
import Ecto.Changeset | ||
import SweetXml | ||
|
||
@primary_key false | ||
@derive Jason.Encoder | ||
@required [:recording_token] | ||
@optional [] | ||
|
||
embedded_schema do | ||
field(:recording_token, :string) | ||
|
||
embeds_one :configuration, Configuration, primary_key: false, on_replace: :update do | ||
@derive Jason.Encoder | ||
field(:content, :string) | ||
field(:maximum_retention_time, :string) | ||
|
||
embeds_one(:source, Source, primary_key: false, on_replace: :update) do | ||
@derive Jason.Encoder | ||
field(:source_id, :string) | ||
field(:name, :string) | ||
field(:location, :string) | ||
field(:description, :string) | ||
field(:address, :string) | ||
end | ||
end | ||
|
||
embeds_one(:tracks, Tracks, primary_key: false, on_replace: :update) do | ||
@derive Jason.Encoder | ||
embeds_many(:track, Track, primary_key: false, on_replace: :delete) do | ||
@derive Jason.Encoder | ||
field(:track_token, :string) | ||
|
||
embeds_one(:configuration, Configuration, primary_key: false, on_replace: :update) do | ||
@derive Jason.Encoder | ||
field(:track_type, :string) | ||
field(:description, :string) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def parse(nil), do: nil | ||
def parse([]), do: nil | ||
|
||
def parse(doc) do | ||
xmap( | ||
doc, | ||
recording_token: ~x"./tt:RecordingToken/text()"so, | ||
configuration: ~x"./tt:Configuration"eo |> transform_by(&parse_configuration/1), | ||
tracks: ~x"./tt:Tracks"eo |> transform_by(&parse_tracks/1) | ||
) | ||
end | ||
|
||
def parse_configuration([]), do: nil | ||
def parse_configuration(nil), do: nil | ||
|
||
def parse_configuration(doc) do | ||
xmap( | ||
doc, | ||
content: ~x"./tt:Content/text()"so, | ||
maximum_retention_time: ~x"./tt:MaximumRetentionTime/text()"so, | ||
source: ~x"./tt:Source"eo |> transform_by(&parse_source/1) | ||
) | ||
end | ||
|
||
def parse_source([]), do: nil | ||
def parse_source(nil), do: nil | ||
|
||
def parse_source(doc) do | ||
xmap( | ||
doc, | ||
source_id: ~x"./tt:SourceId/text()"so, | ||
name: ~x"./tt:Name/text()"so, | ||
location: ~x"./tt:Location/text()"so, | ||
description: ~x"./tt:Description/text()"so, | ||
address: ~x"./tt:Address/text()"so | ||
) | ||
end | ||
|
||
def parse_tracks([]), do: nil | ||
def parse_tracks(nil), do: nil | ||
|
||
def parse_tracks(doc) do | ||
xmap( | ||
doc, | ||
track: ~x"./tt:Track"elo |> transform_by(&parse_track/1) | ||
) | ||
end | ||
|
||
def parse_track([]), do: nil | ||
def parse_track(nil), do: nil | ||
|
||
def parse_track(docs) do | ||
Enum.map(docs, fn doc -> | ||
xmap( | ||
doc, | ||
track_token: ~x"./tt:TrackToken/text()"so, | ||
configuration: ~x"./tt:Configuration"eo |> transform_by(&parse_track_configuration/1) | ||
) | ||
end) | ||
end | ||
|
||
def parse_track_configuration([]), do: nil | ||
def parse_track_configuration(nil), do: nil | ||
|
||
def parse_track_configuration(doc) do | ||
xmap( | ||
doc, | ||
track_type: ~x"./tt:TrackType/text()"so, | ||
description: ~x"./tt:Description/text()"so | ||
) | ||
end | ||
|
||
def to_struct(parsed) do | ||
%__MODULE__{} | ||
|> changeset(parsed) | ||
|> apply_action(:validate) | ||
end | ||
|
||
@spec to_json(%Onvif.Recording.Recording{}) :: | ||
{: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(:configuration, with: &configuration_changeset/2) | ||
|> cast_embed(:tracks, with: &tracks_changeset/2) | ||
end | ||
|
||
def configuration_changeset(module, attrs) do | ||
cast(module, attrs, [:content, :maximum_retention_time]) | ||
|> cast_embed(:source, with: &source_changeset/2) | ||
end | ||
|
||
def source_changeset(module, attrs) do | ||
cast(module, attrs, [:source_id, :name, :location, :description, :address]) | ||
end | ||
|
||
def tracks_changeset(module, attrs) do | ||
cast(module, attrs, []) | ||
|> cast_embed(:track, with: &track_changeset/2) | ||
end | ||
|
||
def track_changeset(module, attrs) do | ||
cast(module, attrs, [:track_token]) | ||
|> cast_embed(:configuration, with: &track_configuration_changeset/2) | ||
end | ||
|
||
def track_configuration_changeset(module, attrs) do | ||
cast(module, attrs, [:track_type, :description]) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
defmodule Onvif.Recording.CreateRecordingTest do | ||
use ExUnit.Case, async: true | ||
|
||
@moduletag capture_log: true | ||
|
||
describe "CreateRecording/2" do | ||
test "create a recording" do | ||
xml_response = File.read!("test/recording/fixture/create_recording_success.xml") | ||
|
||
device = Onvif.Factory.device() | ||
|
||
Mimic.expect(Tesla, :request, fn _client, _opts -> | ||
{:ok, %{status: 200, body: xml_response}} | ||
end) | ||
|
||
{:ok, response_uri} = Onvif.Recording.CreateRecording.request( | ||
device, | ||
config: %Onvif.Recording.Recording.Configuration{ | ||
content: "test", | ||
maximum_retention_time: "PT1H", | ||
source: %Onvif.Recording.Recording.Configuration.Source{ | ||
name: "test", | ||
} | ||
}) | ||
|
||
assert response_uri == "SD_DISK_20200422_123501_A2388AB3" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<SOAP-ENV:Envelope | ||
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:xmime="http://tempuri.org/xmime.xsd" | ||
xmlns:xop="http://www.w3.org/2004/08/xop/include" | ||
xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" | ||
xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" | ||
xmlns:tt="http://www.onvif.org/ver10/schema" | ||
xmlns:acert="http://www.axis.com/vapix/ws/cert" | ||
xmlns:wsrfr="http://docs.oasis-open.org/wsrf/r-2" | ||
xmlns:aa="http://www.axis.com/vapix/ws/action1" | ||
xmlns:acertificates="http://www.axis.com/vapix/ws/certificates" | ||
xmlns:aentry="http://www.axis.com/vapix/ws/entry" | ||
xmlns:aev="http://www.axis.com/vapix/ws/event1" | ||
xmlns:aeva="http://www.axis.com/vapix/ws/embeddedvideoanalytics1" | ||
xmlns:ali1="http://www.axis.com/vapix/ws/light/CommonBinding" | ||
xmlns:ali2="http://www.axis.com/vapix/ws/light/IntensityBinding" | ||
xmlns:ali3="http://www.axis.com/vapix/ws/light/AngleOfIlluminationBinding" | ||
xmlns:ali4="http://www.axis.com/vapix/ws/light/DayNightSynchronizeBinding" | ||
xmlns:ali="http://www.axis.com/vapix/ws/light" | ||
xmlns:apc="http://www.axis.com/vapix/ws/panopsiscalibration1" | ||
xmlns:arth="http://www.axis.com/vapix/ws/recordedtour1" | ||
xmlns:asd="http://www.axis.com/vapix/ws/shockdetection" | ||
xmlns:aweb="http://www.axis.com/vapix/ws/webserver" | ||
xmlns:tan1="http://www.onvif.org/ver20/analytics/wsdl/RuleEngineBinding" | ||
xmlns:tan2="http://www.onvif.org/ver20/analytics/wsdl/AnalyticsEngineBinding" | ||
xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" | ||
xmlns:tds="http://www.onvif.org/ver10/device/wsdl" | ||
xmlns:tev1="http://www.onvif.org/ver10/events/wsdl/NotificationProducerBinding" | ||
xmlns:tev2="http://www.onvif.org/ver10/events/wsdl/EventBinding" | ||
xmlns:tev3="http://www.onvif.org/ver10/events/wsdl/SubscriptionManagerBinding" | ||
xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" | ||
xmlns:tev4="http://www.onvif.org/ver10/events/wsdl/PullPointSubscriptionBinding" | ||
xmlns:tev="http://www.onvif.org/ver10/events/wsdl" | ||
xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" | ||
xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" | ||
xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" | ||
xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" | ||
xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" | ||
xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" | ||
xmlns:trt="http://www.onvif.org/ver10/media/wsdl" | ||
xmlns:tse="http://www.onvif.org/ver10/search/wsdl" | ||
xmlns:ter="http://www.onvif.org/ver10/error" | ||
xmlns:tns1="http://www.onvif.org/ver10/topics" | ||
xmlns:tnsaxis="http://www.axis.com/2009/event/topics"> | ||
<SOAP-ENV:Body> | ||
<trc:CreateRecordingResponse> | ||
<trc:RecordingToken>SD_DISK_20200422_123501_A2388AB3</trc:RecordingToken> | ||
</trc:CreateRecordingResponse> | ||
</SOAP-ENV:Body> | ||
</SOAP-ENV:Envelope> |