danta 0.0.0

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 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
+ };