matterhorn_whymper 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/.rvmrc +62 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +30 -0
- data/Rakefile +8 -0
- data/lib/matterhorn/endpoint.rb +40 -0
- data/lib/matterhorn/endpoint/ingest.rb +124 -0
- data/lib/matterhorn/endpoint/workflow.rb +67 -0
- data/lib/matterhorn/error.rb +15 -0
- data/lib/matterhorn/http_client.rb +156 -0
- data/lib/matterhorn/media_package.rb +110 -0
- data/lib/matterhorn/smil.rb +310 -0
- data/lib/matterhorn/workflow_instance.rb +59 -0
- data/lib/matterhorn_whymper.rb +47 -0
- data/lib/matterhorn_whymper/version.rb +3 -0
- data/matterhorn_whymper.gemspec +29 -0
- data/spec/Matterhorn_whymper_spec.rb +13 -0
- data/spec/endpoints_spec.rb +34 -0
- data/spec/matterhorn.yml.sample +5 -0
- data/spec/spec_helper.rb +16 -0
- metadata +155 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
MzFjMzFkMjcxNDYyMTZlZjM1NjVkMTBmMTUzNmJmNTI1N2ZiN2I1NA==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
MmFkNTAxNDM0M2ZiM2FlMzViNTczYjYzNjcxYzI4YTNjNDNjMjhkYQ==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
ZTc5ZGRlNGNkNGZlY2NhZGI4ZDY5YTgyNWFiMzUwYWQ2NmRmNzg4ZjA5ZTM0
|
|
10
|
+
MmU3MjY3YjNhYzI5ZjFmYWQ2NDIwOGE1ZjExNzY0NmI0ZmNkNGI0NTNkZWQz
|
|
11
|
+
NzVmZjQ3Njg4MGFhOThhNDQwMTc0NzI0NWQ1NWNhNzM4NWJjNTM=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
NDEzZjUwZDMwZjhmZWY3NWI3YjQxODk4ZWViNzEyMDJkNjY4M2EyNmVkMzNi
|
|
14
|
+
YmYwMjVmMjVmNTY2ZGNlZTNhNzkzOWI3ZDM1YWZmNTE3YjQ5NWYzN2U0ODJk
|
|
15
|
+
ZmFjY2FhMDRhYjE3M2FmNTEwNDI0NTA5NmZmZGJmYmMzNjUxYTM=
|
data/.gitignore
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
.bundle
|
|
4
|
+
.config
|
|
5
|
+
.yardoc
|
|
6
|
+
Gemfile.lock
|
|
7
|
+
InstalledFiles
|
|
8
|
+
_yardoc
|
|
9
|
+
coverage
|
|
10
|
+
doc/
|
|
11
|
+
lib/bundler/man
|
|
12
|
+
pkg
|
|
13
|
+
rdoc
|
|
14
|
+
spec/matterhorn.yml
|
|
15
|
+
spec/reports
|
|
16
|
+
test/tmp
|
|
17
|
+
test/version_tmp
|
|
18
|
+
tmp
|
|
19
|
+
*.bundle
|
|
20
|
+
*.so
|
|
21
|
+
*.o
|
|
22
|
+
*.a
|
|
23
|
+
mkmf.log
|
data/.rspec
ADDED
data/.rvmrc
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
|
4
|
+
# development environment upon cd'ing into the directory
|
|
5
|
+
|
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
|
7
|
+
# Only full ruby name is supported here, for short names use:
|
|
8
|
+
# echo "rvm use 1.9.3" > .rvmrc
|
|
9
|
+
environment_id="ruby-1.9.3-p484@matterhorn-endpoint_api"
|
|
10
|
+
|
|
11
|
+
# Uncomment the following lines if you want to verify rvm version per project
|
|
12
|
+
# rvmrc_rvm_version="1.25.19 (stable)" # 1.10.1 seems like a safe start
|
|
13
|
+
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | __rvm_awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
|
14
|
+
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
|
15
|
+
# return 1
|
|
16
|
+
# }
|
|
17
|
+
|
|
18
|
+
# First we attempt to load the desired environment directly from the environment
|
|
19
|
+
# file. This is very fast and efficient compared to running through the entire
|
|
20
|
+
# CLI and selector. If you want feedback on which environment was used then
|
|
21
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
|
22
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
|
23
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
|
24
|
+
then
|
|
25
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
|
26
|
+
for __hook in "${rvm_path:-$HOME/.rvm}/hooks/after_use"*
|
|
27
|
+
do
|
|
28
|
+
if [[ -f "${__hook}" && -x "${__hook}" && -s "${__hook}" ]]
|
|
29
|
+
then \. "${__hook}" || true
|
|
30
|
+
fi
|
|
31
|
+
done
|
|
32
|
+
unset __hook
|
|
33
|
+
if (( ${rvm_use_flag:=1} >= 1 )) # display automatically
|
|
34
|
+
then
|
|
35
|
+
if [[ $- == *i* ]] # check for interactive shells
|
|
36
|
+
then printf "%b" "Using: $(tput setaf 2 2>/dev/null)$GEM_HOME$(tput sgr0 2>/dev/null)
|
|
37
|
+
" # show the user the ruby and gemset they are using in green
|
|
38
|
+
else printf "%b" "Using: $GEM_HOME
|
|
39
|
+
" # don't use colors in non-interactive shells
|
|
40
|
+
fi
|
|
41
|
+
fi
|
|
42
|
+
else
|
|
43
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
|
44
|
+
rvm --create use "$environment_id" || {
|
|
45
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
|
46
|
+
return 1
|
|
47
|
+
}
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# If you use bundler, this might be useful to you:
|
|
51
|
+
# if [[ -s Gemfile ]] && {
|
|
52
|
+
# ! builtin command -v bundle >/dev/null ||
|
|
53
|
+
# builtin command -v bundle | GREP_OPTIONS="" \grep $rvm_path/bin/bundle >/dev/null
|
|
54
|
+
# }
|
|
55
|
+
# then
|
|
56
|
+
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
|
57
|
+
# gem install bundler
|
|
58
|
+
# fi
|
|
59
|
+
# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
|
|
60
|
+
# then
|
|
61
|
+
# bundle install | GREP_OPTIONS="" \grep -vE '^Using|Your bundle is complete'
|
|
62
|
+
# fi
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2014 SWITCH / Daniel Fritschi
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Matterhorn Whymper
|
|
2
|
+
|
|
3
|
+
Ruby wrapper against the Matterhorn Endpoint API
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
Add this line to your application's Gemfile:
|
|
9
|
+
|
|
10
|
+
gem 'matterhorn_whymper'
|
|
11
|
+
|
|
12
|
+
And then execute:
|
|
13
|
+
|
|
14
|
+
$ bundle install
|
|
15
|
+
|
|
16
|
+
Or install it yourself as:
|
|
17
|
+
|
|
18
|
+
$ gem install matterhorn_whymper
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
TODO: Write usage instructions here
|
|
23
|
+
|
|
24
|
+
## Contributing
|
|
25
|
+
|
|
26
|
+
1. Fork it ( https://github.com/switch-ch/matterhorn_whymper/fork )
|
|
27
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
28
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
29
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
30
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Matterhorn
|
|
2
|
+
|
|
3
|
+
class Endpoint
|
|
4
|
+
|
|
5
|
+
# --- attributes -------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
attr_reader :http_client
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# --- initialization ---------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
def self.open(endpoint)
|
|
13
|
+
if endpoint.respond_to? 'to_s'
|
|
14
|
+
endpoint = endpoint.to_s.capitalize
|
|
15
|
+
else
|
|
16
|
+
#TODO: error handling
|
|
17
|
+
end
|
|
18
|
+
endpoint = Object.const_get('Matterhorn').const_get('Endpoint').const_get(endpoint).new
|
|
19
|
+
|
|
20
|
+
yield endpoint
|
|
21
|
+
|
|
22
|
+
endpoint.close
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
@http_client = Matterhorn::HttpClient.new(
|
|
28
|
+
MatterhornWhymper.configuration.uri
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def close
|
|
34
|
+
http_client.close
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
class Matterhorn::Endpoint::Ingest < Matterhorn::Endpoint
|
|
2
|
+
|
|
3
|
+
# --- attributes -------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# --- end point methodes -----------------------------------------------------
|
|
7
|
+
|
|
8
|
+
def addAttachment(file, flavor)
|
|
9
|
+
if @media_pkg_remote.nil?
|
|
10
|
+
raise(Matterhorn::Error, "No media package is available!")
|
|
11
|
+
end
|
|
12
|
+
@media_pkg_local.add_attachment(file, flavor)
|
|
13
|
+
@media_pkg_remote = http_client.post(
|
|
14
|
+
"ingest/addAttachment",
|
|
15
|
+
{ 'flavor' => flavor,
|
|
16
|
+
'mediaPackage' => @media_pkg_remote,
|
|
17
|
+
'BODY' => file
|
|
18
|
+
}
|
|
19
|
+
).body
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def addCatalog(file, flavor)
|
|
24
|
+
if @media_pkg_remote.nil?
|
|
25
|
+
raise(Matterhorn::Error, "No media package is available!")
|
|
26
|
+
end
|
|
27
|
+
@media_pkg_local.add_catalog(file, flavor)
|
|
28
|
+
@media_pkg_remote = http_client.post(
|
|
29
|
+
"ingest/addCatalog",
|
|
30
|
+
{ 'flavor' => flavor,
|
|
31
|
+
'mediaPackage' => @media_pkg_remote,
|
|
32
|
+
'BODY' => file
|
|
33
|
+
}
|
|
34
|
+
).body
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def addDCCatalog(dublin_core)
|
|
39
|
+
if @media_pkg_remote.nil?
|
|
40
|
+
raise(Matterhorn::Error, "No media package is available!")
|
|
41
|
+
end
|
|
42
|
+
@media_pkg_local.add_dc_catalog(dublin_core)
|
|
43
|
+
@media_pkg_remote = http_client.post(
|
|
44
|
+
"ingest/addDCCatalog",
|
|
45
|
+
{ 'flavor' => 'dublincore/episode',
|
|
46
|
+
'mediaPackage' => @media_pkg_remote,
|
|
47
|
+
'dublinCore' => dublin_core
|
|
48
|
+
}
|
|
49
|
+
).body
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def addTrack(file, flavor)
|
|
54
|
+
if @media_pkg_remote.nil?
|
|
55
|
+
raise(Matterhorn::Error, "No media package is available!")
|
|
56
|
+
end
|
|
57
|
+
@media_pkg_local.add_track(file, flavor)
|
|
58
|
+
@media_pkg_remote = http_client.post(
|
|
59
|
+
"ingest/addTrack",
|
|
60
|
+
{ 'flavor' => flavor,
|
|
61
|
+
'mediaPackage' => @media_pkg_remote,
|
|
62
|
+
'BODY' => file
|
|
63
|
+
}
|
|
64
|
+
).body
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def createMediaPackage(path = '')
|
|
69
|
+
if !@media_pkg_remote.nil?
|
|
70
|
+
raise(Matterhorn::Error, "A media package is allready created!")
|
|
71
|
+
end
|
|
72
|
+
@media_pkg_local = Matterhorn::MediaPackage.new(path)
|
|
73
|
+
@media_pkg_remote = http_client.get(
|
|
74
|
+
"ingest/createMediaPackage"
|
|
75
|
+
).body
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def ingest(wdID = 'full', options = {})
|
|
80
|
+
if @media_pkg_remote.nil?
|
|
81
|
+
raise(Matterhorn::Error, "No media package is available!")
|
|
82
|
+
end
|
|
83
|
+
@media_pkg_local.save if !@media_pkg_local.nil?
|
|
84
|
+
options['mediaPackage'] = @media_pkg_remote
|
|
85
|
+
@workflow_inst = http_client.post(
|
|
86
|
+
"ingest/ingest/#{wdID}",
|
|
87
|
+
options
|
|
88
|
+
).body
|
|
89
|
+
workflow_instance
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def media_package(kind = 'local')
|
|
94
|
+
if kind == 'local' && !@media_pkg_local.nil?
|
|
95
|
+
return @media_pkg_local
|
|
96
|
+
elsif !@media_pkg_remote.nil?
|
|
97
|
+
Matterhorn::MediaPackage.new(@media_pkg_remote)
|
|
98
|
+
else
|
|
99
|
+
nil
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def setTitle(title)
|
|
105
|
+
dublin_core = <<DUBLIN_CORE
|
|
106
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
107
|
+
<dublincore xmlns="http://www.opencastproject.org/xsd/1.0/dublincore/" xmlns:dcterms="http://purl.org/dc/terms/">
|
|
108
|
+
<dcterms:title>#{title}</dcterms:title>
|
|
109
|
+
</dublincore>
|
|
110
|
+
DUBLIN_CORE
|
|
111
|
+
addDCCatalog(dublin_core)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def workflow_instance
|
|
116
|
+
if !@workflow_inst.nil?
|
|
117
|
+
Matterhorn::WorkflowInstance.new(@workflow_inst)
|
|
118
|
+
else
|
|
119
|
+
nil
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
class Matterhorn::Endpoint::Workflow < Matterhorn::Endpoint
|
|
2
|
+
|
|
3
|
+
# --- attributes -------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# --- end point methodes -----------------------------------------------------
|
|
7
|
+
|
|
8
|
+
def instance(wi_id)
|
|
9
|
+
@workflow_inst = http_client.get(
|
|
10
|
+
"workflow/instance/#{wi_id}.xml"
|
|
11
|
+
).body
|
|
12
|
+
workflow_instance
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def remove(wi_id, options = {})
|
|
17
|
+
begin
|
|
18
|
+
@workflow_inst = http_client.delete(
|
|
19
|
+
"workflow/remove/#{wi_id}"
|
|
20
|
+
).body
|
|
21
|
+
rescue Matterhorn::HttpClientError => ex
|
|
22
|
+
Rails.logger.warn { "Matterhorn::Workflow::remove | WorkflowInstance[wi_id] could not be stopped!\n" +
|
|
23
|
+
"#{ex.class.name}: #{ex.to_s} / backtrace:\n#{ex.backtrace.join("\n")}" }
|
|
24
|
+
return nil
|
|
25
|
+
rescue => ex
|
|
26
|
+
raise ex
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def resume(wi_id, options = {})
|
|
32
|
+
options['id'] = wi_id
|
|
33
|
+
@workflow_inst = http_client.post(
|
|
34
|
+
"workflow/resume",
|
|
35
|
+
options
|
|
36
|
+
).body
|
|
37
|
+
workflow_instance
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def stop(wi_id, options = {})
|
|
42
|
+
begin
|
|
43
|
+
options['id'] = wi_id
|
|
44
|
+
@workflow_inst = http_client.post(
|
|
45
|
+
"workflow/stop",
|
|
46
|
+
options
|
|
47
|
+
).body
|
|
48
|
+
workflow_instance
|
|
49
|
+
rescue Matterhorn::HttpClientError => ex
|
|
50
|
+
Rails.logger.warn { "Matterhorn::Workflow::stop | WorkflowInstance[wi_id] could not be stopped!\n" +
|
|
51
|
+
"#{ex.class.name}: #{ex.to_s} / backtrace:\n#{ex.backtrace.join("\n")}" }
|
|
52
|
+
return nil
|
|
53
|
+
rescue => ex
|
|
54
|
+
raise ex
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def workflow_instance
|
|
60
|
+
if !@workflow_inst.nil?
|
|
61
|
+
Matterhorn::WorkflowInstance.new(@workflow_inst)
|
|
62
|
+
else
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Matterhorn
|
|
2
|
+
|
|
3
|
+
# --- Matterhorn Exceptions ------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
class Matterhorn::Error < StandardError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class Matterhorn::HttpClientError < Matterhorn::Error
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Matterhorn::HttpServerError < Matterhorn::Error
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
require 'net/http/post/multipart'
|
|
2
|
+
require 'net/http/digest_auth'
|
|
3
|
+
|
|
4
|
+
module Matterhorn
|
|
5
|
+
|
|
6
|
+
class HttpClient
|
|
7
|
+
|
|
8
|
+
# --- attributes -------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
attr_reader :base_uri, :host, :port, :ssl
|
|
11
|
+
|
|
12
|
+
# --- initialization ---------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
def initialize(base_uri)
|
|
15
|
+
@base_uri = URI.parse(base_uri)
|
|
16
|
+
@host = @base_uri.host
|
|
17
|
+
@port = @base_uri.port
|
|
18
|
+
@ssl = @port == 443 ? true : false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def close
|
|
22
|
+
@http_socket.finish if !@http_socket.nil? && @http_socket.started?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# --- http methodes ----------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
def post(url, params = {}, file = nil, filename = nil, mime_type = nil)
|
|
28
|
+
if params.has_key?('BODY') || !file.nil?
|
|
29
|
+
request = multipart_post(url, params, file, filename, mime_type)
|
|
30
|
+
else
|
|
31
|
+
request = singlepart_post(url, params)
|
|
32
|
+
end
|
|
33
|
+
execute_request(request)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get(url)
|
|
38
|
+
request = Net::HTTP::Get.new(base_uri.request_uri + url)
|
|
39
|
+
execute_request(request)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def delete(url)
|
|
44
|
+
request = Net::HTTP::Delete.new(base_uri.request_uri + url)
|
|
45
|
+
execute_request(request)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ========================================================================== #
|
|
50
|
+
# === private section === #
|
|
51
|
+
# ========================================================================== #
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def http_socket
|
|
55
|
+
return @http_socket if !@http_socket.nil? && @http_socket.started?
|
|
56
|
+
@http_socket = Net::HTTP.new(host, port)
|
|
57
|
+
@http_socket.use_ssl = ssl
|
|
58
|
+
@http_socket.start
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def singlepart_post(url, params)
|
|
63
|
+
request = Net::HTTP::Post.new(base_uri.request_uri + url)
|
|
64
|
+
request.set_form_data(params)
|
|
65
|
+
MatterhornWhymper.logger.debug { "Matterhorn::Client::singlepart_post: request = #{request.to_yaml}"}
|
|
66
|
+
request
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def multipart_post(url, params, file, filename, mime_type)
|
|
71
|
+
if file.kind_of?(String)
|
|
72
|
+
file = File.new(file)
|
|
73
|
+
elsif file.kind_of?(File)
|
|
74
|
+
# noting to do
|
|
75
|
+
elsif params['BODY'].kind_of?(String)
|
|
76
|
+
file = File.new(params['BODY'])
|
|
77
|
+
params['BODY'] = nil
|
|
78
|
+
elsif params['BODY'].kind_of?(File)
|
|
79
|
+
file = params['BODY']
|
|
80
|
+
params['BODY'] = nil
|
|
81
|
+
else
|
|
82
|
+
raise(Matterhorn::Error, "Matterhorn::Client::multipart_post: Neither BODY nor file exists!")
|
|
83
|
+
end
|
|
84
|
+
MatterhornWhymper.logger.debug { "Matterhorn::Client::multipart_post: file = #{file.inspect}"}
|
|
85
|
+
if filename.nil?
|
|
86
|
+
filename = File.basename(file.path)
|
|
87
|
+
end
|
|
88
|
+
if mime_type.nil?
|
|
89
|
+
mime_type = MIME::Types.type_for(File.basename(file.path)).first
|
|
90
|
+
end
|
|
91
|
+
params['BODY'] = UploadIO.new(file, mime_type, filename)
|
|
92
|
+
MatterhornWhymper.logger.debug { "Matterhorn::Client::multipart_post: params = #{params.to_yaml}"}
|
|
93
|
+
Net::HTTP::Post::Multipart.new(base_uri.request_uri + url, params)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def execute_request(request)
|
|
98
|
+
head = Net::HTTP::Head.new(request.path)
|
|
99
|
+
head['X-REQUESTED-AUTH'] = 'Digest'
|
|
100
|
+
head['X-Opencast-Matterhorn-Authorization'] = 'true'
|
|
101
|
+
digest_result = http_socket.request(head)
|
|
102
|
+
digest_auth = Net::HTTP::DigestAuth.new
|
|
103
|
+
auth = digest_auth.auth_header(base_uri, digest_result['www-authenticate'], request.method)
|
|
104
|
+
request.add_field('Authorization', auth)
|
|
105
|
+
response = http_socket.request(request)
|
|
106
|
+
case response.code.to_i
|
|
107
|
+
when 200..299
|
|
108
|
+
handle_2xx_ok(request, response)
|
|
109
|
+
when 400..499
|
|
110
|
+
handle_4xx_error(request, response)
|
|
111
|
+
when 500..599
|
|
112
|
+
handle_5xx_error(request, response)
|
|
113
|
+
else
|
|
114
|
+
handle_unknown_error(request, response)
|
|
115
|
+
end
|
|
116
|
+
response
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def handle_2xx_ok(request, response)
|
|
121
|
+
MatterhornWhymper.logger.info { "Matterhorn::Client::execute_request:\n" + log_message(request, response) }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def handle_4xx_error(request, response)
|
|
125
|
+
MatterhornWhymper.logger.error { "Matterhorn::Client::execute_request: Client Error:\n" + log_message(request, response) }
|
|
126
|
+
raise(Matterhorn::HttpClientError, log_message(request, response))
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def handle_5xx_error(request, response)
|
|
130
|
+
MatterhornWhymper.logger.error { "Matterhorn::Client::execute_request: Server Error:\n" + log_message(request, response) }
|
|
131
|
+
raise(Matterhorn::HttpServerError, log_message(request, response))
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def handle_unknown_error(request, response)
|
|
135
|
+
MatterhornWhymper.logger.error { "Matterhorn::Client::execute_request: Server Error:\n" + log_message(request, response) }
|
|
136
|
+
raise(Matterhorn::Error, log_message(request, response))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def log_message(request, response)
|
|
141
|
+
" request = #{log_request(request)}\n" +
|
|
142
|
+
" response = #{log_response(response)}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def log_request(request)
|
|
146
|
+
"#{request.method} #{request.path}"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def log_response(response)
|
|
150
|
+
"#{response.code} #{response.msg}, body:\n#{response.body}\n"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require 'nokogiri'
|
|
2
|
+
|
|
3
|
+
module Matterhorn
|
|
4
|
+
|
|
5
|
+
class MediaPackage
|
|
6
|
+
|
|
7
|
+
# --- const definitions ------------------------------------------------------
|
|
8
|
+
XML_NS_MEDIAPACKAGE = "http://mediapackage.opencastproject.org"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# --- initialization ---------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
def initialize(path, xml = nil)
|
|
14
|
+
@path = path + (path[-1] == '/' ? '' : '/') # guarantee that path ends with a slash
|
|
15
|
+
if !xml.nil?
|
|
16
|
+
@document = Nokogiri::XML(xml)
|
|
17
|
+
else
|
|
18
|
+
@document = Nokogiri::XML::Builder.new do |xml|
|
|
19
|
+
xml.mediapackage('xmlns' => XML_NS_MEDIAPACKAGE) {
|
|
20
|
+
xml.media
|
|
21
|
+
xml.metadata
|
|
22
|
+
xml.attachments
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
.doc
|
|
26
|
+
end
|
|
27
|
+
MatterhornWhymper.logger.debug { "Matterhorn::MediaPackage::initialize | doc = #{to_xml}" }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# --- methodes ---------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
# <attachments>
|
|
34
|
+
# <attachment type="switchcastrecorder/metadata">
|
|
35
|
+
# <tags/>
|
|
36
|
+
# <url>metadata.plist</url>
|
|
37
|
+
# </attachment>
|
|
38
|
+
# </attachments>
|
|
39
|
+
def add_attachment(file, flavor)
|
|
40
|
+
Nokogiri::XML::Builder.with(@document.at('attachments')) do |xml|
|
|
41
|
+
xml.attachment(:type => flavor) {
|
|
42
|
+
xml.tags
|
|
43
|
+
xml.url file.sub(@path, '')
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# <metadata>
|
|
50
|
+
# <catalog type="dublincore/episode">
|
|
51
|
+
# <mimetype>text/xml</mimetype>
|
|
52
|
+
# <tags/>
|
|
53
|
+
# <url>dublincore.xml</url>
|
|
54
|
+
# </catalog>
|
|
55
|
+
# </metadata>
|
|
56
|
+
def add_catalog(file, flavor, mimetype = 'text/xml')
|
|
57
|
+
Nokogiri::XML::Builder.with(@document.at('metadata')) do |xml|
|
|
58
|
+
xml.catalog(:type => flavor) {
|
|
59
|
+
xml.mimetype mimetype
|
|
60
|
+
xml.tags
|
|
61
|
+
xml.url file.sub(@path, '')
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def add_dc_catalog(dublin_core)
|
|
68
|
+
filename = 'dublincore.xml'
|
|
69
|
+
flavor = 'dublincore/episode'
|
|
70
|
+
dc_doc = Nokogiri::XML(dublin_core)
|
|
71
|
+
dc_file = File.join(@path, filename)
|
|
72
|
+
File.open(dc_file, 'w') do |file|
|
|
73
|
+
file.write(dc_doc.to_xml)
|
|
74
|
+
end
|
|
75
|
+
add_catalog(dc_file, flavor)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# <media>
|
|
80
|
+
# <track type="presenter/source+partial">
|
|
81
|
+
# <tags/>
|
|
82
|
+
# <url>source1/mux_2013_12-17T14_51_29_738.mov</url>
|
|
83
|
+
# </track>
|
|
84
|
+
# </media>
|
|
85
|
+
def add_track(file, flavor)
|
|
86
|
+
Nokogiri::XML::Builder.with(@document.at('media')) do |xml|
|
|
87
|
+
xml.track(:type => flavor) {
|
|
88
|
+
xml.tags
|
|
89
|
+
xml.url file.sub(@path, '')
|
|
90
|
+
}
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def save(path = @path)
|
|
96
|
+
manifest_file = File.join(path, 'manifest.xml')
|
|
97
|
+
File.open(manifest_file, 'w') do |file|
|
|
98
|
+
file.write(@document.to_xml)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def to_xml
|
|
104
|
+
@document.to_xml
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
module Matterhorn
|
|
2
|
+
|
|
3
|
+
class Smil
|
|
4
|
+
|
|
5
|
+
# --- const definitions ------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
# --- attributes -------------------------------------------------------------
|
|
8
|
+
attr_reader :head, :body
|
|
9
|
+
|
|
10
|
+
# --- validations ------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# --- callback declarations --------------------------------------------------
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# --- relations --------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# --- initialization ---------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def initialize()
|
|
22
|
+
@head = Smil::Head.new
|
|
23
|
+
@body = Smil::Body.new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# --- methodes ---------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
def save(smil_file)
|
|
29
|
+
File.open(smil_file, 'w') do |file|
|
|
30
|
+
file.write(self.to_xml)
|
|
31
|
+
end
|
|
32
|
+
Rails.logger.debug { "Matterhorn::Smil::save | Smil description =\n#{self.to_xml}" }
|
|
33
|
+
true
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def to_xml
|
|
38
|
+
StringIO.open('', 'w') do |strio|
|
|
39
|
+
bx = Builder::XmlMarkup.new(:target=>strio, :indent=>2)
|
|
40
|
+
bx.instruct! :xml, :version=>'1.1', :encoding => 'UTF-8'
|
|
41
|
+
bx.smil(:xmlns => "http://www.w3.org/ns/SMIL") do
|
|
42
|
+
head.to_xml(bx)
|
|
43
|
+
body.to_xml(bx)
|
|
44
|
+
end
|
|
45
|
+
strio.string
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# ========================================================================== #
|
|
51
|
+
# === protected section === #
|
|
52
|
+
# ========================================================================== #
|
|
53
|
+
protected
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# ========================================================================== #
|
|
57
|
+
# === private section === #
|
|
58
|
+
# ========================================================================== #
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Smil::Head
|
|
66
|
+
|
|
67
|
+
def to_xml(builder)
|
|
68
|
+
builder.head do
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class Smil::Body
|
|
77
|
+
|
|
78
|
+
attr_reader :par_list
|
|
79
|
+
|
|
80
|
+
def initialize()
|
|
81
|
+
@par_list = Array.new
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def add_par()
|
|
85
|
+
par = Smil::Par.new
|
|
86
|
+
@par_list << par
|
|
87
|
+
par
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def to_xml(bx)
|
|
92
|
+
bx.body do
|
|
93
|
+
@par_list.each do |par|
|
|
94
|
+
par.to_xml(bx)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class Smil::Element
|
|
104
|
+
|
|
105
|
+
# --- attributes -------------------------------------------------------------
|
|
106
|
+
attr_reader :start_point, :end_point, :rel_begin, :duration, :parent
|
|
107
|
+
|
|
108
|
+
# --- initialization ---------------------------------------------------------
|
|
109
|
+
def initialize(parent = nil)
|
|
110
|
+
@start_point = nil
|
|
111
|
+
@end_point = nil
|
|
112
|
+
@rel_begin = nil
|
|
113
|
+
@duration = nil
|
|
114
|
+
@parent = parent
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# --- methodes ---------------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
def attr_list
|
|
120
|
+
attr_list = Hash.new
|
|
121
|
+
if !@rel_begin.nil?
|
|
122
|
+
attr_list[:begin] = "#{(@rel_begin * 1000).round.to_s}ms"
|
|
123
|
+
end
|
|
124
|
+
if !@duration.nil?
|
|
125
|
+
attr_list[:dur] = "#{(@duration * 1000).round.to_s}ms"
|
|
126
|
+
end
|
|
127
|
+
attr_list
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# ========================================================================== #
|
|
132
|
+
# === protected section === #
|
|
133
|
+
# ========================================================================== #
|
|
134
|
+
protected
|
|
135
|
+
|
|
136
|
+
def start_point=(new_start_point)
|
|
137
|
+
if new_start_point.kind_of? String
|
|
138
|
+
# start_point is an absolut time position and must be in the format 2013-12-02T14:12:42.364
|
|
139
|
+
new_start_point = new_start_point.to_datetime.to_f
|
|
140
|
+
elsif new_start_point.respond_to?('to_f')
|
|
141
|
+
new_start_point = new_start_point.to_f
|
|
142
|
+
else
|
|
143
|
+
new_start_point = nil
|
|
144
|
+
end
|
|
145
|
+
@start_point = new_start_point
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def end_point=(new_end_point)
|
|
149
|
+
if new_end_point.kind_of? String
|
|
150
|
+
# end_point is an absolut time position and must be in the format 2013-12-02T14:12:42.364
|
|
151
|
+
new_end_point = new_end_point.to_datetime.to_f
|
|
152
|
+
elsif new_end_point.respond_to?('to_f')
|
|
153
|
+
new_end_point = new_end_point.to_f
|
|
154
|
+
else
|
|
155
|
+
new_end_point = nil
|
|
156
|
+
end
|
|
157
|
+
@end_point = new_end_point
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def rel_begin=(new_rel_begin)
|
|
161
|
+
if new_rel_begin.kind_of? Fixnum
|
|
162
|
+
new_rel_begin = new_rel_begin / 1000.0
|
|
163
|
+
elsif new_rel_begin.respond_to?('to_f')
|
|
164
|
+
new_rel_begin = new_rel_begin.to_f
|
|
165
|
+
else
|
|
166
|
+
new_rel_begin = nil
|
|
167
|
+
end
|
|
168
|
+
@rel_begin = new_rel_begin
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def duration=(new_duration)
|
|
172
|
+
if new_duration.kind_of? Fixnum
|
|
173
|
+
# duration is in ms
|
|
174
|
+
new_duration = new_duration / 1000
|
|
175
|
+
elsif duration.respond_to?('to_f')
|
|
176
|
+
# duration is in s
|
|
177
|
+
new_duration = new_duration.to_f
|
|
178
|
+
else
|
|
179
|
+
new_duration = nil
|
|
180
|
+
end
|
|
181
|
+
@end_point = start_point + new_duration if !start_point.nil? && !new_duration.nil?
|
|
182
|
+
@duration = new_duration
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def update(sub_elem)
|
|
186
|
+
if !sub_elem.start_point.nil? && (start_point.nil? || start_point > sub_elem.start_point)
|
|
187
|
+
@start_point = sub_elem.start_point
|
|
188
|
+
else
|
|
189
|
+
# do not update start_point
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
if !sub_elem.end_point.nil? && (end_point.nil? || end_point < sub_elem.end_point)
|
|
193
|
+
@end_point = sub_elem.end_point
|
|
194
|
+
else
|
|
195
|
+
# do not update start_point
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
if !start_point.nil? && !end_point.nil?
|
|
199
|
+
@duration = end_point - start_point
|
|
200
|
+
end
|
|
201
|
+
# update parent if any
|
|
202
|
+
parent.update(self) if !parent.nil?
|
|
203
|
+
propagate(self) if parent.nil?
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def propagate(parent_elem)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class Smil::Par < Smil::Element
|
|
214
|
+
|
|
215
|
+
def initialize()
|
|
216
|
+
super
|
|
217
|
+
@seq_list = Array.new
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def add_seq
|
|
222
|
+
seq = Smil::Seq.new(self)
|
|
223
|
+
@seq_list << seq
|
|
224
|
+
seq
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def propagate(parent_elem)
|
|
229
|
+
@seq_list.each do |seq|
|
|
230
|
+
seq.propagate(self)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def to_xml(bx)
|
|
236
|
+
bx.par(attr_list) do
|
|
237
|
+
@seq_list.each do |seq|
|
|
238
|
+
seq.to_xml(bx)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class Smil::Seq < Smil::Element
|
|
248
|
+
|
|
249
|
+
def initialize(parent)
|
|
250
|
+
super(parent)
|
|
251
|
+
@track_list = Array.new
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def attr_list
|
|
255
|
+
attrib_list = super
|
|
256
|
+
attrib_list.delete(:begin)
|
|
257
|
+
attrib_list
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def add_track(kind, file, start_point, duration)
|
|
261
|
+
track = Smil::Track.new(self, kind, file, start_point, duration)
|
|
262
|
+
@track_list << track
|
|
263
|
+
update(track)
|
|
264
|
+
track
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def propagate(parent_elem)
|
|
268
|
+
@rel_begin = start_point - parent_elem.start_point
|
|
269
|
+
@track_list.each do |track|
|
|
270
|
+
# propagate with par element
|
|
271
|
+
track.propagate(parent_elem)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def to_xml(bx)
|
|
276
|
+
bx.seq(attr_list) do
|
|
277
|
+
@track_list.each do |track|
|
|
278
|
+
track.to_xml(bx)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class Smil::Track < Smil::Element
|
|
287
|
+
|
|
288
|
+
def initialize(parent, kind, file, start_point, duration)
|
|
289
|
+
super(parent)
|
|
290
|
+
@kind = kind
|
|
291
|
+
@src = file
|
|
292
|
+
self.start_point = start_point
|
|
293
|
+
self.duration = duration
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def propagate(parent_elem)
|
|
297
|
+
@rel_begin = start_point - parent_elem.start_point
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def to_xml(bx)
|
|
301
|
+
attributes = attr_list
|
|
302
|
+
if !@src.nil?
|
|
303
|
+
attributes[:src] = @src.to_s
|
|
304
|
+
end
|
|
305
|
+
bx.tag!(@kind, attributes)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'nokogiri'
|
|
2
|
+
|
|
3
|
+
module Matterhorn
|
|
4
|
+
|
|
5
|
+
class WorkflowInstance
|
|
6
|
+
|
|
7
|
+
XML_NS_WORKFLOW = "http://workflow.opencastproject.org"
|
|
8
|
+
|
|
9
|
+
# --- const definitions ------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
# --- attributes -------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
# --- validations ------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
# --- callback declarations --------------------------------------------------
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# --- relations --------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# --- initialization ---------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
def initialize(xml)
|
|
24
|
+
@document = Nokogiri::XML(xml)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# --- methodes ---------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
def id
|
|
30
|
+
@document.xpath('/nsw:workflow/@id', {"nsw" => XML_NS_WORKFLOW}).first.value
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def state
|
|
34
|
+
@document.xpath('/nsw:workflow/@state', {"nsw" => XML_NS_WORKFLOW}).first.value
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def template
|
|
38
|
+
@document.xpath('/nsw:workflow/nsw:template', {"nsw" => XML_NS_WORKFLOW}).first.content
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def to_xml
|
|
42
|
+
@document.to_xml
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# ========================================================================== #
|
|
47
|
+
# === protected section === #
|
|
48
|
+
# ========================================================================== #
|
|
49
|
+
protected
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# ========================================================================== #
|
|
53
|
+
# === private section === #
|
|
54
|
+
# ========================================================================== #
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'matterhorn_whymper/version'
|
|
2
|
+
require 'matterhorn/endpoint'
|
|
3
|
+
require 'matterhorn/endpoint/ingest'
|
|
4
|
+
require 'matterhorn/endpoint/workflow'
|
|
5
|
+
require 'matterhorn/http_client'
|
|
6
|
+
require 'matterhorn/media_package'
|
|
7
|
+
require 'matterhorn/error'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
module MatterhornWhymper
|
|
11
|
+
|
|
12
|
+
def self.info
|
|
13
|
+
"Ruby wrapper against the Matterhorn Endpoint API. Version #{MatterhornWhymper::VERSION}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
attr_accessor :configuration, :logger
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def self.configure
|
|
23
|
+
self.configuration ||= Configuration.new
|
|
24
|
+
if defined?(Rails)
|
|
25
|
+
self.logger = Rails.logger
|
|
26
|
+
else
|
|
27
|
+
require 'logger'
|
|
28
|
+
self.logger = Logger.new(STDOUT)
|
|
29
|
+
end
|
|
30
|
+
yield(configuration) if block_given?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Configuration
|
|
36
|
+
|
|
37
|
+
attr_accessor :system_account_user, :system_account_password, :system_domain, :system_protocol
|
|
38
|
+
|
|
39
|
+
def uri
|
|
40
|
+
"#{system_protocol}://#{system_account_user}:#{system_account_password}@#{system_domain}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'matterhorn_whymper/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "matterhorn_whymper"
|
|
8
|
+
spec.version = MatterhornWhymper::VERSION
|
|
9
|
+
spec.authors = ["Daniel Fritschi"]
|
|
10
|
+
spec.email = ["daniel.fritschi@switch.ch"]
|
|
11
|
+
spec.summary = %q{Ruby wrapper around the Matterhorn Endpoint API}
|
|
12
|
+
spec.description = %q{This Ruby wrapper is designed to write some ruby scripts against the
|
|
13
|
+
Matterhorn Endpoint API}
|
|
14
|
+
spec.homepage = "https://github.com/switch-ch/matterhorn_whymper"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
|
+
spec.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
spec.add_runtime_dependency "multipart-post", "~> 2.0"
|
|
23
|
+
spec.add_runtime_dependency "net-http-digest_auth", "~> 1.4"
|
|
24
|
+
spec.add_runtime_dependency "nokogiri", "~> 1.6"
|
|
25
|
+
|
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
|
27
|
+
spec.add_development_dependency "rake", "~> 10.3"
|
|
28
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
|
29
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe MatterhornWhymper do
|
|
4
|
+
|
|
5
|
+
it "version must be defined" do
|
|
6
|
+
expect(MatterhornWhymper::VERSION).not_to be nil
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "#info" do
|
|
10
|
+
expect(MatterhornWhymper.info).to include MatterhornWhymper::VERSION
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Matterhorn::Endpoint do
|
|
4
|
+
|
|
5
|
+
it "does ingest endpoint available" do
|
|
6
|
+
Matterhorn::Endpoint.open(:ingest) do |ingest_endpoint|
|
|
7
|
+
expect(ingest_endpoint).not_to be nil
|
|
8
|
+
expect(ingest_endpoint.class.name).to eq 'Matterhorn::Endpoint::Ingest'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "does workflow endpoint available" do
|
|
13
|
+
Matterhorn::Endpoint.open(:workflow) do |workflow_endpoint|
|
|
14
|
+
expect(workflow_endpoint).not_to be nil
|
|
15
|
+
expect(workflow_endpoint.class.name).to eq 'Matterhorn::Endpoint::Workflow'
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
describe "Ingest Mediapackages" do
|
|
23
|
+
|
|
24
|
+
it "creates a mediapackage" do
|
|
25
|
+
Matterhorn::Endpoint.open(:ingest) do |ingest_endpoint|
|
|
26
|
+
ingest_endpoint.createMediaPackage()
|
|
27
|
+
mp_local = ingest_endpoint.media_package
|
|
28
|
+
mp_remote = ingest_endpoint.media_package('remote')
|
|
29
|
+
expect(mp_local).not_to be nil
|
|
30
|
+
expect(mp_remote).not_to be nil
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'bundler/setup'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
Bundler.setup
|
|
5
|
+
|
|
6
|
+
require 'matterhorn_whymper' # and any other gems you need
|
|
7
|
+
|
|
8
|
+
RSpec.configure do |config|
|
|
9
|
+
MatterhornWhymper.configure do |mh_config|
|
|
10
|
+
mh_yml = YAML::load_file( "./spec/matterhorn.yml" )
|
|
11
|
+
mh_config.system_account_user = mh_yml['matterhorn']['system_account_user']
|
|
12
|
+
mh_config.system_account_password = mh_yml['matterhorn']['system_account_password']
|
|
13
|
+
mh_config.system_domain = mh_yml['matterhorn']['system_domain']
|
|
14
|
+
mh_config.system_protocol = mh_yml['matterhorn']['system_protocol']
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: matterhorn_whymper
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Daniel Fritschi
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-05-12 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: multipart-post
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: net-http-digest_auth
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ~>
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.4'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ~>
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.4'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: nokogiri
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ~>
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.6'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ~>
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.6'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: bundler
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.6'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ~>
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.6'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rake
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ~>
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '10.3'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ~>
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '10.3'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rspec
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ~>
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '2.14'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ~>
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '2.14'
|
|
97
|
+
description: ! "This Ruby wrapper is designed to write some ruby scripts against the\n
|
|
98
|
+
\ Matterhorn Endpoint API"
|
|
99
|
+
email:
|
|
100
|
+
- daniel.fritschi@switch.ch
|
|
101
|
+
executables: []
|
|
102
|
+
extensions: []
|
|
103
|
+
extra_rdoc_files: []
|
|
104
|
+
files:
|
|
105
|
+
- .gitignore
|
|
106
|
+
- .rspec
|
|
107
|
+
- .rvmrc
|
|
108
|
+
- Gemfile
|
|
109
|
+
- LICENSE.txt
|
|
110
|
+
- README.md
|
|
111
|
+
- Rakefile
|
|
112
|
+
- lib/matterhorn/endpoint.rb
|
|
113
|
+
- lib/matterhorn/endpoint/ingest.rb
|
|
114
|
+
- lib/matterhorn/endpoint/workflow.rb
|
|
115
|
+
- lib/matterhorn/error.rb
|
|
116
|
+
- lib/matterhorn/http_client.rb
|
|
117
|
+
- lib/matterhorn/media_package.rb
|
|
118
|
+
- lib/matterhorn/smil.rb
|
|
119
|
+
- lib/matterhorn/workflow_instance.rb
|
|
120
|
+
- lib/matterhorn_whymper.rb
|
|
121
|
+
- lib/matterhorn_whymper/version.rb
|
|
122
|
+
- matterhorn_whymper.gemspec
|
|
123
|
+
- spec/Matterhorn_whymper_spec.rb
|
|
124
|
+
- spec/endpoints_spec.rb
|
|
125
|
+
- spec/matterhorn.yml.sample
|
|
126
|
+
- spec/spec_helper.rb
|
|
127
|
+
homepage: https://github.com/switch-ch/matterhorn_whymper
|
|
128
|
+
licenses:
|
|
129
|
+
- MIT
|
|
130
|
+
metadata: {}
|
|
131
|
+
post_install_message:
|
|
132
|
+
rdoc_options: []
|
|
133
|
+
require_paths:
|
|
134
|
+
- lib
|
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - ! '>='
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: '0'
|
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - ! '>='
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
requirements: []
|
|
146
|
+
rubyforge_project:
|
|
147
|
+
rubygems_version: 2.2.2
|
|
148
|
+
signing_key:
|
|
149
|
+
specification_version: 4
|
|
150
|
+
summary: Ruby wrapper around the Matterhorn Endpoint API
|
|
151
|
+
test_files:
|
|
152
|
+
- spec/Matterhorn_whymper_spec.rb
|
|
153
|
+
- spec/endpoints_spec.rb
|
|
154
|
+
- spec/matterhorn.yml.sample
|
|
155
|
+
- spec/spec_helper.rb
|