danta 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 04256810a41ebae351de08e5a2d03e45813eddf5
4
+ data.tar.gz: 6c8275981d760bbde30eaeee46c5f638b11a3300
5
+ SHA512:
6
+ metadata.gz: a8b52d0972003071f25444929a0af4f4ea07b72141d6a2962dd70e940dba61337cd11ee95961d9109e9bc9a796809b9fc456cbd24a8e63e0e640e9e4eda41cf8
7
+ data.tar.gz: b1f0432b0d712234d80705b5f02a65584d98ca8fc036b7b088bca83d7131dcf2ec025b8310d8dcd32736e01a3c1a292e72d12797990c3def6b09a067ca3af214
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Carlos Chacon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # Danta
2
+ Danta is a web app for easy video playing in your Raspberry Pi.
3
+
4
+ ## Installation
5
+
6
+ ### Install ruby
7
+
8
+ We're going to use [RVM](https://rvm.io/rvm/install) to install Ruby.
9
+
10
+ ```
11
+ \curl -sSL https://get.rvm.io | bash -s stable --ruby
12
+ ```
13
+
14
+ ### Install xdotool and omxplayer
15
+
16
+ Danta uses [Pecari](https://github.com/caedocha/pecari) to play videos, so install the following packages:
17
+
18
+ ```
19
+ sudo apt-get install xdotool omxplayer
20
+ ```
21
+
22
+ ### Add Video Library file
23
+
24
+ Danta needs to know where is your video library. Add a `video_library.yml` file in the home directory.
25
+
26
+ ```
27
+ cd ~
28
+ vim video_library.yml # Add your video library path here.
29
+ ```
30
+
31
+ With the following data:
32
+
33
+ ```
34
+ --
35
+ videos:
36
+ - '/path/to/videos/directory/'
37
+
38
+ ```
39
+
40
+ ### Install Danta gem
41
+
42
+ ```
43
+ gem install danta
44
+ ```
45
+
46
+ ## Start Danta
47
+
48
+ Just call the danta command and the app will be ready to use.
49
+
50
+ ```
51
+ danta
52
+ ```
53
+
54
+ Access it with your smartphone's browser using the RPi's IP address. This is mine, for example:
55
+
56
+ ```
57
+ 192.168.1.10:9292
58
+ ```
59
+
60
+ ### Danta Environment Variables
61
+
62
+ Danta's behavior can be customized with the following environment variables:
63
+
64
+ ```
65
+ DANTA_HOST # Overrides the default host, 0.0.0.0
66
+ DANTA_PORT # Overrides the default port, 9292
67
+ DANTA_VIDEO_LIBRARY # Overrides the default video library directory, the current user's home directory (~)
68
+ ```
69
+
70
+ Examples:
71
+
72
+ ```
73
+ export DANTA_HOST=localhost
74
+ export DANTA_PORT=9999
75
+ export DANTA_VIDEO_LIBRARY=/Other/video/library/directory
76
+ ```
77
+
78
+ ## Starting Danta at boot
79
+
80
+ Probably, you want to have Danta starting during boot time. In order to do this, edit the `rc.local` file:
81
+
82
+ ```
83
+ sudo vim /etc/rc.local
84
+ ```
85
+
86
+ Add the following line at the end of the file:
87
+
88
+ ```
89
+ danta &
90
+ ```
91
+
92
+ Save, exit and reboot the RPi.
93
+
94
+ ## Supported Formats
95
+
96
+ Danta only supports `mkv`, `mov` and `mp4` videos. Any other video type is filtered out.
97
+
98
+ For more information, check [Pecari Usage Guide](https://github.com/caedocha/pecari#usage)
99
+
100
+ ## Contact
101
+
102
+ You can send me an email to caedo.00 at gmail dot com. All feedback or questions are welcomed.
data/bin/danta ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'danta'
4
+
5
+ Danta::Root.new.start
data/lib/danta/api.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+ require 'sinatra-websocket'
3
+ require_relative 'request_handler'
4
+
5
+ module Danta
6
+
7
+ class Api < Sinatra::Base
8
+
9
+ get '/ws' do
10
+ RequestHandler.new(request: request).process
11
+ end
12
+
13
+ run! if __FILE__ == $0
14
+
15
+ end
16
+
17
+ end
data/lib/danta/app.rb ADDED
@@ -0,0 +1,20 @@
1
+ module Danta
2
+
3
+ class App < Sinatra::Base
4
+
5
+ set :status, true
6
+ set :public_folder, public_dir
7
+
8
+ get '/' do
9
+ send_file(File.join(public_dir, 'index.html'))
10
+ end
11
+
12
+ def public_dir
13
+ File.join(File.dirname(__FILE__), 'public')
14
+ end
15
+
16
+ run! if __FILE__ == $0
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,90 @@
1
+ require 'json'
2
+ require 'pecari'
3
+ require_relative 'video_library'
4
+
5
+ class Dispatcher
6
+
7
+ attr_reader :raw_data
8
+
9
+ def initialize(raw_data:)
10
+ @raw_data = raw_data
11
+ end
12
+
13
+ def dispatch
14
+ case action
15
+ when 'videos'
16
+ videos_response
17
+ when 'launch'
18
+ launch_action
19
+ when 'exec'
20
+ exec_action
21
+ else
22
+ unrecognized_response
23
+ end
24
+ rescue StandardError => e
25
+ invalid_response(e)
26
+ end
27
+
28
+ def videos_response
29
+ {
30
+ action: action,
31
+ status: 'success',
32
+ data: Danta::VideoLibrary.new.videos.to_json
33
+ }.to_json
34
+ end
35
+
36
+ def launch_action
37
+ Pecari::Player.launch(CGI.unescape(params['video']))
38
+ launch_response
39
+ end
40
+
41
+ def launch_response
42
+ {
43
+ action: action,
44
+ status: 'success',
45
+ data: "playing #{params['video']}"
46
+ }.to_json
47
+ end
48
+
49
+ def exec_action
50
+ Pecari::Player.send(params['command'])
51
+ exec_response
52
+ end
53
+
54
+ def exec_response
55
+ {
56
+ action: action,
57
+ status: 'success',
58
+ data: "executing #{params['command']}"
59
+ }.to_json
60
+ end
61
+
62
+ def unrecognized_response
63
+ {
64
+ action: unrecognized_action,
65
+ status: 'fail',
66
+ data: ''
67
+ }.to_json
68
+ end
69
+
70
+ def invalid_response(exception)
71
+ {
72
+ action: 'invalid_action',
73
+ status: 'fail',
74
+ data: exception.message
75
+ }.to_json
76
+ end
77
+
78
+ def data
79
+ @data ||= JSON.parse(raw_data)
80
+ end
81
+
82
+ def action
83
+ @action ||= data['action']
84
+ end
85
+
86
+ def params
87
+ @params ||= data['params']
88
+ end
89
+
90
+ end
@@ -0,0 +1,57 @@
1
+ require 'json'
2
+
3
+ module Library
4
+
5
+ class Node
6
+
7
+ attr_accessor :name
8
+ attr_accessor :nodes
9
+ attr_accessor :path
10
+ attr_accessor :parent
11
+
12
+ def initialize(name:, parent: nil, nodes: [])
13
+ @name = name
14
+ @nodes = nodes
15
+ @parent = parent
16
+ end
17
+
18
+ def root?
19
+ parent.empty?
20
+ end
21
+
22
+ def leaf?
23
+ nodes.empty?
24
+ end
25
+
26
+ def to_h
27
+ {
28
+ name: name,
29
+ path: path,
30
+ nodes: nodes.map(&:to_h)
31
+ }
32
+ end
33
+
34
+ def to_json
35
+ to_h.to_json
36
+ end
37
+
38
+ def path
39
+ @path ||= build_path
40
+ end
41
+
42
+ private
43
+
44
+ def build_path
45
+ next_parent = parent
46
+ parent_paths = [name]
47
+ while next_parent
48
+ parent_paths << next_parent.name
49
+ next_parent = next_parent.parent
50
+ end
51
+ parent_paths.reverse.join('/')
52
+ File.join(['/', parent_paths.reverse].flatten)
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,31 @@
1
+ module Library
2
+
3
+ class NullNode
4
+
5
+ def name
6
+ "nodeless"
7
+ end
8
+
9
+ def root?
10
+ false
11
+ end
12
+
13
+ def leaf?
14
+ true
15
+ end
16
+
17
+ def to_h
18
+ {}
19
+ end
20
+
21
+ def to_json
22
+ to_h.to_json
23
+ end
24
+
25
+ def path
26
+ ''
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,85 @@
1
+ require_relative 'node'
2
+ require_relative 'null_node'
3
+
4
+ module Library
5
+
6
+ class Tree
7
+
8
+ attr_reader :nodes
9
+ attr_accessor :paths
10
+
11
+ def initialize(paths:)
12
+ @paths = paths
13
+ end
14
+
15
+ def nodes
16
+ @nodes ||= root_nodes
17
+ end
18
+
19
+ def to_h
20
+ nodes.map(&:to_h)
21
+ end
22
+
23
+ def to_json
24
+ to_h.to_json
25
+ end
26
+
27
+ private
28
+
29
+ def splitted_paths
30
+ paths.map { |path| path.split('/').reject { |path| path.empty? } }
31
+ end
32
+
33
+ def unlinked_nodes
34
+ @unlinked_nodes ||= splitted_paths
35
+ .map do |paths|
36
+ paths.map do |path|
37
+ Node.new(name: path)
38
+ end
39
+ end
40
+ end
41
+
42
+ def linked_nodes
43
+ @linked_nodes ||= unlinked_nodes.map do |unlinked_nodes|
44
+ root_nodes = []
45
+ unlinked_nodes.each_cons(2).each_with_index do |(parent, child), index|
46
+ if(index == 0)
47
+ root_nodes << parent
48
+ end
49
+ child.parent = parent
50
+ parent.nodes << child
51
+ end
52
+ root_nodes
53
+ end
54
+ end
55
+
56
+ def root_nodes
57
+ backup_nodes = linked_nodes.dup
58
+ temp_nodes = backup_nodes.first.dup
59
+ backup_nodes.shift
60
+ backup_nodes.each_with_object(temp_nodes) do |nod, tmp|
61
+ rewire_nodes(node: nod.first, base_node: tmp.first)
62
+ end
63
+ temp_nodes
64
+ end
65
+
66
+ def rewire_nodes(node:, base_node:, backup_parent: nil)
67
+ if(node.name == base_node.name)
68
+ x = base_node.nodes.detect { |n| n.name == node.nodes.first.name } || base_node.nodes.first || NullNode.new
69
+ if x.name == "nodeless"
70
+ rewire_nodes(node: node.nodes.first, base_node: x, backup_parent: base_node)
71
+ else
72
+ rewire_nodes(node: node.nodes.first, base_node: x)
73
+ end
74
+ elsif(base_node.name == "nodeless")
75
+ node.parent = backup_parent
76
+ backup_parent.nodes << node
77
+ else
78
+ node.parent = base_node.parent
79
+ base_node.parent.nodes << node
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1 @@
1
+ .treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}
@@ -0,0 +1,15 @@
1
+ #player .btn {
2
+ margin: 10px 10px 0px 0px;
3
+ }
4
+
5
+ #controls {
6
+ text-align: center;
7
+ }
8
+
9
+ .node-tree {
10
+ overflow:hidden;
11
+ white-space:nowrap;
12
+ text-overflow:ellipsis;
13
+ width:100%;
14
+ display:block;
15
+ }
@@ -0,0 +1,49 @@
1
+ <html>
2
+ <head>
3
+ <title>Danta Video Player</title>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
7
+ <link rel="stylesheet" href="css/bootstrap-treeview.min.css">
8
+ <link rel="stylesheet" href="css/danta.css">
9
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
10
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
11
+ <script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>
12
+ <script src="js/bootstrap-treeview.min.js"></script>
13
+ <script src="js/web_socket_client.js"></script>
14
+ <script src="js/response_dispatcher.js"></script>
15
+ <script src="js/videos_response.js"></script>
16
+ <script src="js/video_tree.js"></script>
17
+ <script src="js/video_library.js"></script>
18
+ <script src="js/player_actions.js"></script>
19
+ <script src="js/player_modal.js"></script>
20
+ <script src="js/danta.js"></script>
21
+ </head>
22
+ <body>
23
+ <div class="container">
24
+ <h1>Danta Video Player</h1>
25
+ <div id="tree"></div>
26
+ <div id="player" class="modal" role="dialog">
27
+ <div class="modal-dialog">
28
+ <div class="modal-content">
29
+ <div class="modal-header">
30
+ Player
31
+ </div>
32
+ <div class="modal-body">
33
+ <div id="controls">
34
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.play()"><span class="glyphicon glyphicon-play"></span></button>
35
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.pause()"><span class="glyphicon glyphicon-pause"></span></button>
36
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.fastBackward()"><span class="glyphicon glyphicon-fast-backward"></span></button>
37
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.fastForward()"><span class="glyphicon glyphicon-fast-forward"></span></button>
38
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.mute()"><span class="glyphicon glyphicon-volume-off"></span></button>
39
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.turnVolumeDown()"><span class="glyphicon glyphicon-volume-down"></span></button>
40
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.turnVolumeUp()"><span class="glyphicon glyphicon-volume-up"></span></button>
41
+ <button type="button" class="btn btn-default btn-lg" onclick="playerActions.quit()"><span class="glyphicon glyphicon-off"></span></button>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </body>
49
+ </html>
@@ -0,0 +1 @@
1
+ !function(a,b,c,d){"use strict";var e="treeview",f={};f.settings={injectStyle:!0,levels:2,expandIcon:"glyphicon glyphicon-plus",collapseIcon:"glyphicon glyphicon-minus",emptyIcon:"glyphicon",nodeIcon:"",selectedIcon:"",checkedIcon:"glyphicon glyphicon-check",uncheckedIcon:"glyphicon glyphicon-unchecked",color:d,backColor:d,borderColor:d,onhoverColor:"#F5F5F5",selectedColor:"#FFFFFF",selectedBackColor:"#428bca",searchResultColor:"#D9534F",searchResultBackColor:d,enableLinks:!1,highlightSelected:!0,highlightSearchResults:!0,showBorder:!0,showIcon:!0,showCheckbox:!1,showTags:!1,multiSelect:!1,onNodeChecked:d,onNodeCollapsed:d,onNodeDisabled:d,onNodeEnabled:d,onNodeExpanded:d,onNodeSelected:d,onNodeUnchecked:d,onNodeUnselected:d,onSearchComplete:d,onSearchCleared:d},f.options={silent:!1,ignoreChildren:!1},f.searchOptions={ignoreCase:!0,exactMatch:!1,revealResults:!0};var g=function(b,c){return this.$element=a(b),this.elementId=b.id,this.styleId=this.elementId+"-style",this.init(c),{options:this.options,init:a.proxy(this.init,this),remove:a.proxy(this.remove,this),getNode:a.proxy(this.getNode,this),getParent:a.proxy(this.getParent,this),getSiblings:a.proxy(this.getSiblings,this),getSelected:a.proxy(this.getSelected,this),getUnselected:a.proxy(this.getUnselected,this),getExpanded:a.proxy(this.getExpanded,this),getCollapsed:a.proxy(this.getCollapsed,this),getChecked:a.proxy(this.getChecked,this),getUnchecked:a.proxy(this.getUnchecked,this),getDisabled:a.proxy(this.getDisabled,this),getEnabled:a.proxy(this.getEnabled,this),selectNode:a.proxy(this.selectNode,this),unselectNode:a.proxy(this.unselectNode,this),toggleNodeSelected:a.proxy(this.toggleNodeSelected,this),collapseAll:a.proxy(this.collapseAll,this),collapseNode:a.proxy(this.collapseNode,this),expandAll:a.proxy(this.expandAll,this),expandNode:a.proxy(this.expandNode,this),toggleNodeExpanded:a.proxy(this.toggleNodeExpanded,this),revealNode:a.proxy(this.revealNode,this),checkAll:a.proxy(this.checkAll,this),checkNode:a.proxy(this.checkNode,this),uncheckAll:a.proxy(this.uncheckAll,this),uncheckNode:a.proxy(this.uncheckNode,this),toggleNodeChecked:a.proxy(this.toggleNodeChecked,this),disableAll:a.proxy(this.disableAll,this),disableNode:a.proxy(this.disableNode,this),enableAll:a.proxy(this.enableAll,this),enableNode:a.proxy(this.enableNode,this),toggleNodeDisabled:a.proxy(this.toggleNodeDisabled,this),search:a.proxy(this.search,this),clearSearch:a.proxy(this.clearSearch,this)}};g.prototype.init=function(b){this.tree=[],this.nodes=[],b.data&&("string"==typeof b.data&&(b.data=a.parseJSON(b.data)),this.tree=a.extend(!0,[],b.data),delete b.data),this.options=a.extend({},f.settings,b),this.destroy(),this.subscribeEvents(),this.setInitialStates({nodes:this.tree},0),this.render()},g.prototype.remove=function(){this.destroy(),a.removeData(this,e),a("#"+this.styleId).remove()},g.prototype.destroy=function(){this.initialized&&(this.$wrapper.remove(),this.$wrapper=null,this.unsubscribeEvents(),this.initialized=!1)},g.prototype.unsubscribeEvents=function(){this.$element.off("click"),this.$element.off("nodeChecked"),this.$element.off("nodeCollapsed"),this.$element.off("nodeDisabled"),this.$element.off("nodeEnabled"),this.$element.off("nodeExpanded"),this.$element.off("nodeSelected"),this.$element.off("nodeUnchecked"),this.$element.off("nodeUnselected"),this.$element.off("searchComplete"),this.$element.off("searchCleared")},g.prototype.subscribeEvents=function(){this.unsubscribeEvents(),this.$element.on("click",a.proxy(this.clickHandler,this)),"function"==typeof this.options.onNodeChecked&&this.$element.on("nodeChecked",this.options.onNodeChecked),"function"==typeof this.options.onNodeCollapsed&&this.$element.on("nodeCollapsed",this.options.onNodeCollapsed),"function"==typeof this.options.onNodeDisabled&&this.$element.on("nodeDisabled",this.options.onNodeDisabled),"function"==typeof this.options.onNodeEnabled&&this.$element.on("nodeEnabled",this.options.onNodeEnabled),"function"==typeof this.options.onNodeExpanded&&this.$element.on("nodeExpanded",this.options.onNodeExpanded),"function"==typeof this.options.onNodeSelected&&this.$element.on("nodeSelected",this.options.onNodeSelected),"function"==typeof this.options.onNodeUnchecked&&this.$element.on("nodeUnchecked",this.options.onNodeUnchecked),"function"==typeof this.options.onNodeUnselected&&this.$element.on("nodeUnselected",this.options.onNodeUnselected),"function"==typeof this.options.onSearchComplete&&this.$element.on("searchComplete",this.options.onSearchComplete),"function"==typeof this.options.onSearchCleared&&this.$element.on("searchCleared",this.options.onSearchCleared)},g.prototype.setInitialStates=function(b,c){if(b.nodes){c+=1;var d=b,e=this;a.each(b.nodes,function(a,b){b.nodeId=e.nodes.length,b.parentId=d.nodeId,b.hasOwnProperty("selectable")||(b.selectable=!0),b.state=b.state||{},b.state.hasOwnProperty("checked")||(b.state.checked=!1),b.state.hasOwnProperty("disabled")||(b.state.disabled=!1),b.state.hasOwnProperty("expanded")||(!b.state.disabled&&c<e.options.levels&&b.nodes&&b.nodes.length>0?b.state.expanded=!0:b.state.expanded=!1),b.state.hasOwnProperty("selected")||(b.state.selected=!1),e.nodes.push(b),b.nodes&&e.setInitialStates(b,c)})}},g.prototype.clickHandler=function(b){this.options.enableLinks||b.preventDefault();var c=a(b.target),d=this.findNode(c);if(d&&!d.state.disabled){var e=c.attr("class")?c.attr("class").split(" "):[];-1!==e.indexOf("expand-icon")?(this.toggleExpandedState(d,f.options),this.render()):-1!==e.indexOf("check-icon")?(this.toggleCheckedState(d,f.options),this.render()):(d.selectable?this.toggleSelectedState(d,f.options):this.toggleExpandedState(d,f.options),this.render())}},g.prototype.findNode=function(a){var b=a.closest("li.list-group-item").attr("data-nodeid"),c=this.nodes[b];return c||console.log("Error: node does not exist"),c},g.prototype.toggleExpandedState=function(a,b){a&&this.setExpandedState(a,!a.state.expanded,b)},g.prototype.setExpandedState=function(b,c,d){c!==b.state.expanded&&(c&&b.nodes?(b.state.expanded=!0,d.silent||this.$element.trigger("nodeExpanded",a.extend(!0,{},b))):c||(b.state.expanded=!1,d.silent||this.$element.trigger("nodeCollapsed",a.extend(!0,{},b)),b.nodes&&!d.ignoreChildren&&a.each(b.nodes,a.proxy(function(a,b){this.setExpandedState(b,!1,d)},this))))},g.prototype.toggleSelectedState=function(a,b){a&&this.setSelectedState(a,!a.state.selected,b)},g.prototype.setSelectedState=function(b,c,d){c!==b.state.selected&&(c?(this.options.multiSelect||a.each(this.findNodes("true","g","state.selected"),a.proxy(function(a,b){this.setSelectedState(b,!1,d)},this)),b.state.selected=!0,d.silent||this.$element.trigger("nodeSelected",a.extend(!0,{},b))):(b.state.selected=!1,d.silent||this.$element.trigger("nodeUnselected",a.extend(!0,{},b))))},g.prototype.toggleCheckedState=function(a,b){a&&this.setCheckedState(a,!a.state.checked,b)},g.prototype.setCheckedState=function(b,c,d){c!==b.state.checked&&(c?(b.state.checked=!0,d.silent||this.$element.trigger("nodeChecked",a.extend(!0,{},b))):(b.state.checked=!1,d.silent||this.$element.trigger("nodeUnchecked",a.extend(!0,{},b))))},g.prototype.setDisabledState=function(b,c,d){c!==b.state.disabled&&(c?(b.state.disabled=!0,this.setExpandedState(b,!1,d),this.setSelectedState(b,!1,d),this.setCheckedState(b,!1,d),d.silent||this.$element.trigger("nodeDisabled",a.extend(!0,{},b))):(b.state.disabled=!1,d.silent||this.$element.trigger("nodeEnabled",a.extend(!0,{},b))))},g.prototype.render=function(){this.initialized||(this.$element.addClass(e),this.$wrapper=a(this.template.list),this.injectStyle(),this.initialized=!0),this.$element.empty().append(this.$wrapper.empty()),this.buildTree(this.tree,0)},g.prototype.buildTree=function(b,c){if(b){c+=1;var d=this;a.each(b,function(b,e){for(var f=a(d.template.item).addClass("node-"+d.elementId).addClass(e.state.checked?"node-checked":"").addClass(e.state.disabled?"node-disabled":"").addClass(e.state.selected?"node-selected":"").addClass(e.searchResult?"search-result":"").attr("data-nodeid",e.nodeId).attr("style",d.buildStyleOverride(e)),g=0;c-1>g;g++)f.append(d.template.indent);var h=[];if(e.nodes?(h.push("expand-icon"),h.push(e.state.expanded?d.options.collapseIcon:d.options.expandIcon)):h.push(d.options.emptyIcon),f.append(a(d.template.icon).addClass(h.join(" "))),d.options.showIcon){var h=["node-icon"];h.push(e.icon||d.options.nodeIcon),e.state.selected&&(h.pop(),h.push(e.selectedIcon||d.options.selectedIcon||e.icon||d.options.nodeIcon)),f.append(a(d.template.icon).addClass(h.join(" ")))}if(d.options.showCheckbox){var h=["check-icon"];h.push(e.state.checked?d.options.checkedIcon:d.options.uncheckedIcon),f.append(a(d.template.icon).addClass(h.join(" ")))}return f.append(d.options.enableLinks?a(d.template.link).attr("href",e.href).append(e.text):e.text),d.options.showTags&&e.tags&&a.each(e.tags,function(b,c){f.append(a(d.template.badge).append(c))}),d.$wrapper.append(f),e.nodes&&e.state.expanded&&!e.state.disabled?d.buildTree(e.nodes,c):void 0})}},g.prototype.buildStyleOverride=function(a){if(a.state.disabled)return"";var b=a.color,c=a.backColor;return this.options.highlightSelected&&a.state.selected&&(this.options.selectedColor&&(b=this.options.selectedColor),this.options.selectedBackColor&&(c=this.options.selectedBackColor)),this.options.highlightSearchResults&&a.searchResult&&!a.state.disabled&&(this.options.searchResultColor&&(b=this.options.searchResultColor),this.options.searchResultBackColor&&(c=this.options.searchResultBackColor)),"color:"+b+";background-color:"+c+";"},g.prototype.injectStyle=function(){this.options.injectStyle&&!c.getElementById(this.styleId)&&a('<style type="text/css" id="'+this.styleId+'"> '+this.buildStyle()+" </style>").appendTo("head")},g.prototype.buildStyle=function(){var a=".node-"+this.elementId+"{";return this.options.color&&(a+="color:"+this.options.color+";"),this.options.backColor&&(a+="background-color:"+this.options.backColor+";"),this.options.showBorder?this.options.borderColor&&(a+="border:1px solid "+this.options.borderColor+";"):a+="border:none;",a+="}",this.options.onhoverColor&&(a+=".node-"+this.elementId+":not(.node-disabled):hover{background-color:"+this.options.onhoverColor+";}"),this.css+a},g.prototype.template={list:'<ul class="list-group"></ul>',item:'<li class="list-group-item"></li>',indent:'<span class="indent"></span>',icon:'<span class="icon"></span>',link:'<a href="#" style="color:inherit;"></a>',badge:'<span class="badge"></span>'},g.prototype.css=".treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed}",g.prototype.getNode=function(a){return this.nodes[a]},g.prototype.getParent=function(a){var b=this.identifyNode(a);return this.nodes[b.parentId]},g.prototype.getSiblings=function(a){var b=this.identifyNode(a),c=this.getParent(b),d=c?c.nodes:this.tree;return d.filter(function(a){return a.nodeId!==b.nodeId})},g.prototype.getSelected=function(){return this.findNodes("true","g","state.selected")},g.prototype.getUnselected=function(){return this.findNodes("false","g","state.selected")},g.prototype.getExpanded=function(){return this.findNodes("true","g","state.expanded")},g.prototype.getCollapsed=function(){return this.findNodes("false","g","state.expanded")},g.prototype.getChecked=function(){return this.findNodes("true","g","state.checked")},g.prototype.getUnchecked=function(){return this.findNodes("false","g","state.checked")},g.prototype.getDisabled=function(){return this.findNodes("true","g","state.disabled")},g.prototype.getEnabled=function(){return this.findNodes("false","g","state.disabled")},g.prototype.selectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!0,b)},this)),this.render()},g.prototype.unselectNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setSelectedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeSelected=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleSelectedState(a,b)},this)),this.render()},g.prototype.collapseAll=function(b){var c=this.findNodes("true","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.collapseNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!1,b)},this)),this.render()},g.prototype.expandAll=function(b){if(b=a.extend({},f.options,b),b&&b.levels)this.expandLevels(this.tree,b.levels,b);else{var c=this.findNodes("false","g","state.expanded");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setExpandedState(a,!0,b)},this))}this.render()},g.prototype.expandNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setExpandedState(a,!0,b),a.nodes&&b&&b.levels&&this.expandLevels(a.nodes,b.levels-1,b)},this)),this.render()},g.prototype.expandLevels=function(b,c,d){d=a.extend({},f.options,d),a.each(b,a.proxy(function(a,b){this.setExpandedState(b,c>0?!0:!1,d),b.nodes&&this.expandLevels(b.nodes,c-1,d)},this))},g.prototype.revealNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){for(var c=this.getParent(a);c;)this.setExpandedState(c,!0,b),c=this.getParent(c)},this)),this.render()},g.prototype.toggleNodeExpanded=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleExpandedState(a,b)},this)),this.render()},g.prototype.checkAll=function(b){var c=this.findNodes("false","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.checkNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!0,b)},this)),this.render()},g.prototype.uncheckAll=function(b){var c=this.findNodes("true","g","state.checked");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.uncheckNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setCheckedState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeChecked=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.toggleCheckedState(a,b)},this)),this.render()},g.prototype.disableAll=function(b){var c=this.findNodes("false","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.disableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!0,b)},this)),this.render()},g.prototype.enableAll=function(b){var c=this.findNodes("true","g","state.disabled");this.forEachIdentifier(c,b,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.enableNode=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!1,b)},this)),this.render()},g.prototype.toggleNodeDisabled=function(b,c){this.forEachIdentifier(b,c,a.proxy(function(a,b){this.setDisabledState(a,!a.state.disabled,b)},this)),this.render()},g.prototype.forEachIdentifier=function(b,c,d){c=a.extend({},f.options,c),b instanceof Array||(b=[b]),a.each(b,a.proxy(function(a,b){d(this.identifyNode(b),c)},this))},g.prototype.identifyNode=function(a){return"number"==typeof a?this.nodes[a]:a},g.prototype.search=function(b,c){c=a.extend({},f.searchOptions,c),this.clearSearch({render:!1});var d=[];if(b&&b.length>0){c.exactMatch&&(b="^"+b+"$");var e="g";c.ignoreCase&&(e+="i"),d=this.findNodes(b,e),a.each(d,function(a,b){b.searchResult=!0})}return c.revealResults?this.revealNode(d):this.render(),this.$element.trigger("searchComplete",a.extend(!0,{},d)),d},g.prototype.clearSearch=function(b){b=a.extend({},{render:!0},b);var c=a.each(this.findNodes("true","g","searchResult"),function(a,b){b.searchResult=!1});b.render&&this.render(),this.$element.trigger("searchCleared",a.extend(!0,{},c))},g.prototype.findNodes=function(b,c,d){c=c||"g",d=d||"text";var e=this;return a.grep(this.nodes,function(a){var f=e.getNodeValue(a,d);return"string"==typeof f?f.match(new RegExp(b,c)):void 0})},g.prototype.getNodeValue=function(a,b){var c=b.indexOf(".");if(c>0){var e=a[b.substring(0,c)],f=b.substring(c+1,b.length);return this.getNodeValue(e,f)}return a.hasOwnProperty(b)?a[b].toString():d};var h=function(a){b.console&&b.console.error(a)};a.fn[e]=function(b,c){var d;return this.each(function(){var f=a.data(this,e);"string"==typeof b?f?a.isFunction(f[b])&&"_"!==b.charAt(0)?(c instanceof Array||(c=[c]),d=f[b].apply(f,c)):h("No such method : "+b):h("Not initialized, can not call method : "+b):"boolean"==typeof b?d=f:a.data(this,e,new g(this,a.extend(!0,{},b)))}),d||this}}(jQuery,window,document);
@@ -0,0 +1,22 @@
1
+ $(document).ready(function() {
2
+ danta.init();
3
+ });
4
+
5
+ var danta = {
6
+ init: function() {
7
+ this.connectWebSocketClient();
8
+ this.initTree();
9
+ this.initPlayer();
10
+ },
11
+ connectWebSocketClient: function() {
12
+ webSocketClient.connect();
13
+ },
14
+ initTree: function() {
15
+ videoLibrary.get();
16
+ },
17
+ initPlayer: function() {
18
+ playerModal.init(
19
+ function() { videoTree.deselectAllNodes(); }
20
+ );
21
+ }
22
+ };