ektoplayer 0.1.12 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ektoplayer/application.rb +49 -19
- data/lib/ektoplayer/bindings.rb +91 -87
- data/lib/ektoplayer/browsepage.rb +14 -27
- data/lib/ektoplayer/common.rb +12 -67
- data/lib/ektoplayer/compat.rb +5 -11
- data/lib/ektoplayer/config.rb +52 -17
- data/lib/ektoplayer/controllers/browser.rb +10 -5
- data/lib/ektoplayer/database.rb +7 -20
- data/lib/ektoplayer/download/externaldownload.rb +65 -0
- data/lib/ektoplayer/download/rubydownload.rb +69 -0
- data/lib/ektoplayer/icurses/curses.rb +18 -2
- data/lib/ektoplayer/icurses/{ffi_ncurses.rb → ffi-ncurses.rb} +1 -0
- data/lib/ektoplayer/icurses/ncurses.rb +10 -0
- data/lib/ektoplayer/icurses.rb +13 -5
- data/lib/ektoplayer/models/browser.rb +11 -11
- data/lib/ektoplayer/models/player.rb +4 -5
- data/lib/ektoplayer/operations/browser.rb +9 -1
- data/lib/ektoplayer/operations/playlist.rb +1 -1
- data/lib/ektoplayer/players/mpg_wrapper_player.rb +98 -40
- data/lib/ektoplayer/theme.rb +78 -63
- data/lib/ektoplayer/trackloader.rb +25 -74
- data/lib/ektoplayer/ui/colors.rb +33 -5
- data/lib/ektoplayer/ui/widgets/container.rb +1 -1
- data/lib/ektoplayer/ui/widgets/listwidget.rb +35 -34
- data/lib/ektoplayer/ui/widgets.rb +19 -0
- data/lib/ektoplayer/ui.rb +22 -23
- data/lib/ektoplayer/updater.rb +3 -4
- data/lib/ektoplayer/views/browser.rb +7 -2
- data/lib/ektoplayer/views/help.rb +5 -2
- data/lib/ektoplayer/views/info.rb +22 -27
- data/lib/ektoplayer/views/playinginfo.rb +20 -19
- data/lib/ektoplayer/views/playlist.rb +8 -3
- data/lib/ektoplayer/views/progressbar.rb +26 -33
- data/lib/ektoplayer/views/splash.rb +14 -22
- data/lib/ektoplayer/views/trackrenderer.rb +14 -10
- metadata +7 -5
data/lib/ektoplayer/config.rb
CHANGED
@@ -24,12 +24,14 @@ module Ektoplayer
|
|
24
24
|
|
25
25
|
def self.parse_simple_format(format)
|
26
26
|
self._parse_markup(format).map do |fmt|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
fmt[:curses_attrs]
|
27
|
+
fmt[:curses_attrs] = [
|
28
|
+
(fmt[:fg] and Integer(fmt[:fg]) rescue fmt[:fg].to_sym),
|
29
|
+
(fmt[:bg] and Integer(fmt[:bg]) rescue fmt[:bg].to_sym),
|
30
|
+
]
|
31
|
+
fmt[:curses_attrs] << :bold if fmt[:bold]
|
32
|
+
fmt[:curses_attrs] << :blink if fmt[:blink]
|
33
|
+
fmt[:curses_attrs] << :standout if fmt[:standout]
|
34
|
+
fmt[:curses_attrs] << :underline if fmt[:underline]
|
33
35
|
fmt
|
34
36
|
end
|
35
37
|
end
|
@@ -56,14 +58,28 @@ module Ektoplayer
|
|
56
58
|
<album rel="30" fg="red" />
|
57
59
|
<title rel="33" fg="yellow" />
|
58
60
|
<styles rel="20" fg="cyan" />
|
59
|
-
<bpm size="
|
61
|
+
<bpm size="3" fg="green" justify="right" />}.squeeze(' ').freeze
|
60
62
|
|
61
|
-
|
63
|
+
DEFAULT_PLAYINGINFO_FORMAT_TOP =
|
62
64
|
'<text fg="black"><< </text><title bold="on" fg="yellow" /><text fg="black"> >></text>'.freeze
|
63
65
|
|
64
|
-
|
66
|
+
DEFAULT_PLAYINGINFO_FORMAT_BOTTOM =
|
65
67
|
'<artist bold="on" fg="blue" /><text> - </text><album bold="on" fg="red" /><text> (</text><year fg="cyan" /><text>)</text>'.freeze
|
66
68
|
|
69
|
+
DEFAULT_PLAYLIST_FORMAT_256 = %{
|
70
|
+
<number size="3" fg="97" />
|
71
|
+
<artist rel="25" fg="24" />
|
72
|
+
<album rel="30" fg="160" />
|
73
|
+
<title rel="33" fg="178" />
|
74
|
+
<styles rel="20" fg="37" />
|
75
|
+
<bpm size="3" fg="28" justify="right" />}.squeeze(' ').freeze
|
76
|
+
|
77
|
+
DEFAULT_PLAYINGINFO_FORMAT_TOP_256 =
|
78
|
+
'<text fg="236"><< </text><title bold="on" fg="178" /><text fg="236"> >></text>'.freeze
|
79
|
+
|
80
|
+
DEFAULT_PLAYINGINFO_FORMAT_BOTTOM_256 =
|
81
|
+
'<artist bold="on" fg="24" /><text> - </text><album bold="on" fg="160" /><text> (</text><year fg="37" /><text>)</text>'.freeze
|
82
|
+
|
67
83
|
def register(key, description, default, method=nil)
|
68
84
|
# parameter `description` is used by tools/mkconfig.rb, but not here
|
69
85
|
|
@@ -118,7 +134,7 @@ module Ektoplayer
|
|
118
134
|
|
119
135
|
reg :playlist_load_newest,
|
120
136
|
%{How many tracks from database should be added to
|
121
|
-
the playlist on application start.},
|
137
|
+
the playlist on application start.}, 1000
|
122
138
|
|
123
139
|
reg :use_cache,
|
124
140
|
%{Enable/disable local mp3 cache.
|
@@ -143,12 +159,20 @@ module Ektoplayer
|
|
143
159
|
'Number of donwload threads during database update',
|
144
160
|
20, lambda { |v| fail if Integer(v) < 1; Integer(v) }
|
145
161
|
|
146
|
-
|
162
|
+
# - Playlist
|
163
|
+
reg 'playlist.format', 'Format of playlist columns',
|
147
164
|
DEFAULT_PLAYLIST_FORMAT, ColumnFormat.method(:parse_column_format)
|
148
165
|
|
149
|
-
reg 'playlist.
|
166
|
+
reg 'playlist.format_256', 'Format of playlist columns (256 colors)',
|
167
|
+
DEFAULT_PLAYLIST_FORMAT_256, ColumnFormat.method(:parse_column_format)
|
168
|
+
|
169
|
+
# - Browser
|
170
|
+
reg 'browser.format', 'Format of browser columns',
|
150
171
|
DEFAULT_PLAYLIST_FORMAT, ColumnFormat.method(:parse_column_format)
|
151
172
|
|
173
|
+
reg 'browser.format_256', 'Format of browser columns (256 colors)',
|
174
|
+
DEFAULT_PLAYLIST_FORMAT_256, ColumnFormat.method(:parse_column_format)
|
175
|
+
|
152
176
|
# - Progressbar
|
153
177
|
reg 'progressbar.display',
|
154
178
|
'Enable/disable progressbar', true
|
@@ -163,12 +187,24 @@ module Ektoplayer
|
|
163
187
|
reg 'playinginfo.display',
|
164
188
|
'Enable/display playinginfo', true
|
165
189
|
|
166
|
-
reg 'playinginfo.
|
167
|
-
'Format of first line in playinginfo',
|
190
|
+
reg 'playinginfo.format_top',
|
191
|
+
'Format of first line in playinginfo',
|
192
|
+
DEFAULT_PLAYINGINFO_FORMAT_TOP,
|
193
|
+
ColumnFormat.method(:parse_simple_format)
|
194
|
+
|
195
|
+
reg 'playinginfo.format_top_256',
|
196
|
+
'Format of first line in playinginfo (256 colors)',
|
197
|
+
DEFAULT_PLAYINGINFO_FORMAT_TOP_256,
|
198
|
+
ColumnFormat.method(:parse_simple_format)
|
199
|
+
|
200
|
+
reg 'playinginfo.format_bottom',
|
201
|
+
'Format of second line in playinginfo',
|
202
|
+
DEFAULT_PLAYINGINFO_FORMAT_BOTTOM,
|
168
203
|
ColumnFormat.method(:parse_simple_format)
|
169
204
|
|
170
|
-
reg 'playinginfo.
|
171
|
-
'Format of second line in playinginfo',
|
205
|
+
reg 'playinginfo.format_bottom_256',
|
206
|
+
'Format of second line in playinginfo (256 colors)',
|
207
|
+
DEFAULT_PLAYINGINFO_FORMAT_BOTTOM_256,
|
172
208
|
ColumnFormat.method(:parse_simple_format)
|
173
209
|
|
174
210
|
# - Tabbar
|
@@ -232,7 +268,6 @@ module Ektoplayer
|
|
232
268
|
begin
|
233
269
|
cb = callbacks[command.to_sym]
|
234
270
|
cb.call(*args)
|
235
|
-
#fail "Command '#{command}' given args: #{args.size}, wanted #{cb.arity}" if args.size != cb.arity
|
236
271
|
rescue
|
237
272
|
fail "#{file}:#{$.}: #{command}: #{$!}"
|
238
273
|
end
|
@@ -16,19 +16,24 @@ module Ektoplayer
|
|
16
16
|
each { |op| register.(op, &view.method(op)) }
|
17
17
|
|
18
18
|
register.(:enter) do
|
19
|
-
|
19
|
+
selection = view.get_selection
|
20
|
+
|
21
|
+
operations.send(:'browser.enter', selection[0])
|
22
|
+
|
23
|
+
if selection.size > 1
|
24
|
+
selection[1..-1].each do |index|
|
25
|
+
operations.send(:'browser.add_to_playlist', index)
|
26
|
+
end
|
27
|
+
end
|
20
28
|
end
|
21
29
|
|
22
30
|
register.(:add_to_playlist) do
|
23
|
-
#if tracks = browser.tracks(view.selected)
|
24
31
|
view.get_selection.each do |index|
|
25
32
|
operations.send(:'browser.add_to_playlist', index)
|
26
33
|
end
|
27
|
-
#end
|
28
34
|
end
|
29
35
|
|
30
|
-
|
31
|
-
view.mouse.on(65536) do view.up(5) end
|
36
|
+
view.mouse.on(65536) do view.up(5) end
|
32
37
|
view.mouse.on(2097152) do view.down(5) end
|
33
38
|
|
34
39
|
[ICurses::BUTTON1_DOUBLE_CLICKED, ICurses::BUTTON3_CLICKED].each do |btn|
|
data/lib/ektoplayer/database.rb
CHANGED
@@ -25,12 +25,7 @@ module Ektoplayer
|
|
25
25
|
|
26
26
|
a.artist AS album_artist,
|
27
27
|
a.title AS album,
|
28
|
-
a.released_by AS released_by,
|
29
|
-
a.released_by_url AS released_by_url,
|
30
|
-
a.posted_by AS posted_by,
|
31
|
-
a.posted_by_url AS posted_by_url,
|
32
28
|
a.cover_url AS cover_url,
|
33
|
-
a.category AS category,
|
34
29
|
a.description AS description,
|
35
30
|
a.date AS date,
|
36
31
|
a.rating AS rating,
|
@@ -75,12 +70,7 @@ module Ektoplayer
|
|
75
70
|
url TEXT NOT NULL,
|
76
71
|
title TEXT NOT NULL,
|
77
72
|
artist TEXT,
|
78
|
-
released_by TEXT,
|
79
|
-
released_by_url TEXT,
|
80
|
-
posted_by TEXT,
|
81
|
-
posted_by_url TEXT,
|
82
73
|
cover_url TEXT,
|
83
|
-
category TEXT,
|
84
74
|
description TEXT,
|
85
75
|
date DATE,
|
86
76
|
rating FLOAT NOT NULL DEFAULT -1,
|
@@ -144,10 +134,8 @@ module Ektoplayer
|
|
144
134
|
insert_into(table, hash, mode: :replace)
|
145
135
|
end
|
146
136
|
|
147
|
-
def execute(query, params=
|
148
|
-
|
149
|
-
stm.bind_params(*params) if params
|
150
|
-
stm.execute.to_a
|
137
|
+
def execute(query, params=[])
|
138
|
+
@db.execute(query, *params)
|
151
139
|
rescue
|
152
140
|
Application.log(self, $!)
|
153
141
|
end
|
@@ -156,7 +144,7 @@ module Ektoplayer
|
|
156
144
|
columns: ?*,
|
157
145
|
filters: [],
|
158
146
|
group_by: 'url',
|
159
|
-
order_by: 'album,
|
147
|
+
order_by: 'album,number',
|
160
148
|
limit: nil
|
161
149
|
)
|
162
150
|
where_clauses, where_params = [], []
|
@@ -182,7 +170,7 @@ module Ektoplayer
|
|
182
170
|
|
183
171
|
limit = "LIMIT #{limit}" if limit
|
184
172
|
|
185
|
-
|
173
|
+
query = SELECT % {
|
186
174
|
SELECT_COLUMNS: columns,
|
187
175
|
WHERE: where_clauses.join(' '),
|
188
176
|
GROUP_BY: group_by,
|
@@ -190,8 +178,7 @@ module Ektoplayer
|
|
190
178
|
LIMIT: limit
|
191
179
|
}
|
192
180
|
|
193
|
-
|
194
|
-
stm.execute.to_a
|
181
|
+
@db.execute(query, *where_params)
|
195
182
|
rescue
|
196
183
|
Application.log(self, $!)
|
197
184
|
end
|
@@ -201,11 +188,11 @@ module Ektoplayer
|
|
201
188
|
end
|
202
189
|
|
203
190
|
def track_count
|
204
|
-
@db.
|
191
|
+
@db.get_first_value('SELECT COUNT(*) FROM tracks')
|
205
192
|
end
|
206
193
|
|
207
194
|
def album_count
|
208
|
-
@db.
|
195
|
+
@db.get_first_value('SELECT COUNT(*) FROM albums')
|
209
196
|
end
|
210
197
|
end
|
211
198
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
require_relative '../events'
|
5
|
+
|
6
|
+
class ExternalDownload
|
7
|
+
attr_reader :events, :url, :progress, :filename, :error
|
8
|
+
|
9
|
+
def initialize(url, filename)
|
10
|
+
@events = Events.new(:completed, :failed)
|
11
|
+
@url = URI.parse(url)
|
12
|
+
@filename = filename
|
13
|
+
@progress = 0
|
14
|
+
@error = nil
|
15
|
+
@tries = 3
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get_wget_cmd(url, file)
|
19
|
+
%w(wget -nv --show-progress --progress=dot:binary -O) + [file, url]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get_curl_cmd(url, file)
|
23
|
+
%w(curl -# -o) + [file, url]
|
24
|
+
end
|
25
|
+
|
26
|
+
def start!
|
27
|
+
Thread.new do
|
28
|
+
args = CMD.(@url.to_s, @filename)
|
29
|
+
dl_in, dl_out, dl_err, @dl_proc = Open3.popen3(*args)
|
30
|
+
|
31
|
+
begin
|
32
|
+
while (line = dl_err.readpartial(1024))
|
33
|
+
@last_line = line
|
34
|
+
|
35
|
+
if (progress = line.scan(/(\d+(\.\d+)?%)/)[0][0].delete(?%).to_f rescue nil)
|
36
|
+
@progress = progress
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
@dl_proc.join
|
45
|
+
raise if @dl_proc.value.exitstatus > 0
|
46
|
+
@progress = 100.0
|
47
|
+
@events.trigger(:completed)
|
48
|
+
rescue
|
49
|
+
@events.trigger(:failed, (@error = @last_line))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
sleep 0.1 while @dl_proc.nil?
|
54
|
+
sleep 0.2
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
if system('wget --version >/dev/null 2>/dev/null')
|
59
|
+
CMD = method :get_wget_cmd
|
60
|
+
elsif system('curl --version >/dev/null 2>/dev/null')
|
61
|
+
CMD = method :get_curl_cmd
|
62
|
+
else
|
63
|
+
fail LoadError, 'wget/curl not installed'
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
require_relative '../events'
|
5
|
+
|
6
|
+
class RubyDownload
|
7
|
+
attr_reader :events, :url, :filename, :error
|
8
|
+
|
9
|
+
def initialize(url, filename)
|
10
|
+
@events = Events.new(:completed, :failed)
|
11
|
+
@url = URI.parse(url)
|
12
|
+
@filename = filename
|
13
|
+
@bytes_read = 0
|
14
|
+
@error, @total = nil, nil
|
15
|
+
@tries = 3
|
16
|
+
end
|
17
|
+
|
18
|
+
def progress
|
19
|
+
(@bytes_read.to_f / @total * 100) rescue 0).clamp(0, 100).to_f
|
20
|
+
end
|
21
|
+
|
22
|
+
def start!
|
23
|
+
Thread.new do
|
24
|
+
success = false
|
25
|
+
|
26
|
+
@tries.times do |try|
|
27
|
+
begin
|
28
|
+
do_download
|
29
|
+
@events.trigger(:completed)
|
30
|
+
success = true
|
31
|
+
break
|
32
|
+
rescue
|
33
|
+
@_lasterror = $!
|
34
|
+
sleep 3
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
unless success
|
39
|
+
@events.trigger(:failed, @_lasterror)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
sleep 0.1 while @total.nil?
|
44
|
+
sleep 0.2
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
private def do_download
|
49
|
+
@file = File.open(filename, ?w)
|
50
|
+
@bytes_read, @total, @error = 0, nil, nil
|
51
|
+
|
52
|
+
http = Net::HTTP.new(@url.host, @url.port)
|
53
|
+
|
54
|
+
http.request(Net::HTTP::Get.new(@url.request_uri)) do |res|
|
55
|
+
fail res.body unless res.code == '200'
|
56
|
+
|
57
|
+
@total = res.header['Content-Length'].to_i
|
58
|
+
|
59
|
+
res.read_body do |chunk|
|
60
|
+
@bytes_read += chunk.size
|
61
|
+
@file << chunk
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
fail 'filesize mismatch' if @bytes_read != @total
|
66
|
+
ensure
|
67
|
+
(@file.close rescue nil) if @file
|
68
|
+
end
|
69
|
+
end
|
@@ -17,10 +17,25 @@ module Curses
|
|
17
17
|
alias_method :"get#{method}", method.to_sym
|
18
18
|
end
|
19
19
|
|
20
|
+
def leaveok(*_); end # Curses does not
|
21
|
+
def notimeout(*_); end # provide these functions
|
22
|
+
|
20
23
|
alias :timeout :timeout=
|
21
|
-
alias :notimeout :nodelay= #todo
|
22
24
|
alias :nodelay :nodelay=
|
23
25
|
|
26
|
+
def bkgd(attr)
|
27
|
+
@bkgd_color = attr
|
28
|
+
end
|
29
|
+
alias :bkgdset :bkgd
|
30
|
+
|
31
|
+
def erase
|
32
|
+
setpos(0, 0)
|
33
|
+
attrset((@bkgd_color or 0))
|
34
|
+
addstr(' ' * (maxx * maxy))
|
35
|
+
attroff((@bkgd_color or 0))
|
36
|
+
setpos(0, 0)
|
37
|
+
end
|
38
|
+
|
24
39
|
alias :mvwin :move # 'fix' this Gem
|
25
40
|
def move(y, x)
|
26
41
|
setpos(y, x)
|
@@ -28,7 +43,8 @@ module Curses
|
|
28
43
|
end
|
29
44
|
|
30
45
|
class Pad < Window
|
31
|
-
alias :pnoutrefresh :
|
46
|
+
alias :pnoutrefresh :noutrefresh
|
47
|
+
alias :prefresh :refresh
|
32
48
|
end
|
33
49
|
end
|
34
50
|
|
@@ -17,6 +17,7 @@ module Ncurses
|
|
17
17
|
end
|
18
18
|
|
19
19
|
%w(getcurx getcury getmaxx getmaxy getbegx getbegy
|
20
|
+
clearok idlok idcok immedok leaveok setscrreg scrollok nl nonl
|
20
21
|
keypad nodelay notimeout prefresh pnoutrefresh).each do |meth|
|
21
22
|
define_method(meth) do |*args|
|
22
23
|
Ncurses.send(meth, @w, *args)
|
@@ -36,6 +37,15 @@ module Ncurses
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
40
|
+
|
41
|
+
if $USING_CURSES == 'ncurses'
|
42
|
+
### FIX: 'attrset' in ncurses is broken!
|
43
|
+
def attrset(attributes)
|
44
|
+
Ncurses.send(:wattr_get, @w, old_a=[], old_c=[], nil)
|
45
|
+
Ncurses.send(:wattroff, @w, old_a[0] | old_c[0])
|
46
|
+
Ncurses.send(:wattron, @w, attributes)
|
47
|
+
end
|
48
|
+
end
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
data/lib/ektoplayer/icurses.rb
CHANGED
@@ -9,13 +9,21 @@
|
|
9
9
|
end
|
10
10
|
|
11
11
|
fail %{
|
12
|
-
No
|
13
|
-
-
|
14
|
-
-
|
15
|
-
- ncurses-ruby
|
16
|
-
-
|
12
|
+
No module for ncurses found. Please install one of the following gems:
|
13
|
+
- ffi-ncurses (preferred)
|
14
|
+
- ncursesw (good)
|
15
|
+
- ncurses-ruby (good)
|
16
|
+
- curses (works...)
|
17
17
|
|
18
18
|
Maybe your distribution ships one of these already as a package.
|
19
|
+
|
20
|
+
Arch Linux:
|
21
|
+
yaourt -S ruby-curses # or
|
22
|
+
yaourt -S ruby-ncursesw
|
23
|
+
|
24
|
+
Debian / Ubuntu:
|
25
|
+
apt-get install ruby-ncurses
|
26
|
+
|
19
27
|
} unless $USING_CURSES
|
20
28
|
|
21
29
|
require_relative 'icurses/sugar'
|
@@ -6,13 +6,11 @@ module Ektoplayer
|
|
6
6
|
PARENT_DIRECTORY = '..'.freeze
|
7
7
|
|
8
8
|
PATHS = {
|
9
|
-
artist:
|
10
|
-
album:
|
11
|
-
style:
|
12
|
-
year:
|
13
|
-
title:
|
14
|
-
released_by: [:released_by].freeze,
|
15
|
-
posted_by: [:posted_by ].freeze
|
9
|
+
artist: [:artist].freeze,
|
10
|
+
album: [:album ].freeze,
|
11
|
+
style: [:style ].freeze,
|
12
|
+
year: [:year ].freeze,
|
13
|
+
title: [].freeze
|
16
14
|
}.freeze
|
17
15
|
|
18
16
|
def initialize(client)
|
@@ -36,16 +34,18 @@ module Ektoplayer
|
|
36
34
|
end
|
37
35
|
|
38
36
|
def enter(index)
|
39
|
-
return unless (sub = current.enter(index))
|
37
|
+
return false unless (sub = current.enter(index))
|
40
38
|
return back() if sub == :parent
|
41
39
|
@stack.push(sub)
|
42
40
|
@events.trigger(:changed)
|
41
|
+
true
|
43
42
|
end
|
44
43
|
|
45
44
|
def back
|
46
|
-
return unless @stack.size > 1
|
45
|
+
return false unless @stack.size > 1
|
47
46
|
@stack.pop
|
48
47
|
@events.trigger(:changed)
|
48
|
+
true
|
49
49
|
end
|
50
50
|
|
51
51
|
class BrowsableCollection
|
@@ -91,7 +91,7 @@ module Ektoplayer
|
|
91
91
|
return [] if index == 0
|
92
92
|
return [ @contents[index] ]
|
93
93
|
else
|
94
|
-
@database.select(filters: new_filters(index))
|
94
|
+
@database.select(filters: new_filters(index))
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -121,7 +121,7 @@ module Ektoplayer
|
|
121
121
|
|
122
122
|
def tracks(index)
|
123
123
|
@database.select(
|
124
|
-
order_by: CONTENTS[index].to_s + ",album,
|
124
|
+
order_by: 'album,' + CONTENTS[index].to_s + ",album,number"
|
125
125
|
)
|
126
126
|
end
|
127
127
|
end
|
@@ -8,11 +8,12 @@ module Ektoplayer
|
|
8
8
|
super()
|
9
9
|
@client = client
|
10
10
|
@player = MpgWrapperPlayer.new
|
11
|
-
@events
|
12
|
-
|
11
|
+
@events = @player.events
|
12
|
+
#@events.register(:position_change, :track_completed, :pause, :stop, :play)
|
13
|
+
#@player.events.on_all(&@events.method(:trigger))
|
13
14
|
|
14
15
|
%w(pause toggle stop forward backward seek
|
15
|
-
length position position_percent
|
16
|
+
length position position_percent can_http?).each do |m|
|
16
17
|
self.define_singleton_method(m, &@player.method(m))
|
17
18
|
end
|
18
19
|
end
|
@@ -21,8 +22,6 @@ module Ektoplayer
|
|
21
22
|
Application.log(self, 'playing', file)
|
22
23
|
@player.play(file) rescue Application.log(self, $!)
|
23
24
|
end
|
24
|
-
|
25
|
-
def close; @player.close end
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
@@ -7,8 +7,16 @@ module Ektoplayer
|
|
7
7
|
# +add_to_playlist+:: see
|
8
8
|
def initialize(operations, browser, playlist)
|
9
9
|
register = operations.with_register('browser.')
|
10
|
-
register.(:enter, &browser.method(:enter))
|
11
10
|
register.(:back, &browser.method(:back))
|
11
|
+
|
12
|
+
register.(:enter) do |index|
|
13
|
+
unless browser.enter(index)
|
14
|
+
tracks = browser.tracks(index)
|
15
|
+
playlist.add(*tracks)
|
16
|
+
operations.send(:'playlist.play', playlist.size - tracks.size)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
12
20
|
register.(:add_to_playlist) do |index|
|
13
21
|
tracks = browser.tracks(index)
|
14
22
|
playlist.add(*tracks)
|
@@ -35,7 +35,7 @@ module Ektoplayer
|
|
35
35
|
return unless track = @playlist[index]
|
36
36
|
@playlist.current_playing=(index)
|
37
37
|
Thread.new do
|
38
|
-
@player.play(@trackloader.get_track_file(track['url']))
|
38
|
+
@player.play(@trackloader.get_track_file(track['url'], http_okay: @player.can_http?))
|
39
39
|
end.join(0.3) # prevent too many hits
|
40
40
|
end
|
41
41
|
|