rubio-radio 0.0.5 → 0.0.7
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 +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +55 -21
- data/TODO.md +1 -7
- data/exe/rubio +13 -7
- data/lib/rubio/model/bookmark.rb +2 -2
- data/lib/rubio/model/player.rb +116 -16
- data/lib/rubio/model/radio_browser.rb +1 -1
- data/lib/rubio/model/radio_presenter.rb +99 -0
- data/lib/rubio/model/station.rb +1 -1
- data/lib/rubio/version.rb +1 -1
- data/lib/rubio/view/radio.rb +91 -103
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7aae7e45f3433a76e59a907ee6f8ca6c979b0f250236ed86261e841c1f3fd14b
|
4
|
+
data.tar.gz: 270b02be3f3e86878a0d0e4d763ce29a26a148ba3bcee40d1991415c528e3733
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 763eb84cfcee8ea9abb090b0e7b9c8b47e962fcfde3e6a6100b0e0e119d6a2b022e251cf81a6b19609494e3a106b9bc8e53025e525c702095092a84c46fc1947
|
7
|
+
data.tar.gz: 4bba95c7e203ba49c1cc96f6103fa57e4b4e2359141ed81f99e1799b3c81b301254a5a334f15f512326850a3156caa78101a1cb67aad2a57bc85ed327a52ca6a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.7
|
4
|
+
|
5
|
+
- Add country property to radio stations
|
6
|
+
|
7
|
+
## 0.0.6
|
8
|
+
|
9
|
+
- Command option `--[no-]margins` to show/hide margins around window content
|
10
|
+
- Command option `--[no-]info` to show/hide currently playing (song) info when using `vlc -I rc` backend only [true]
|
11
|
+
- Change the default backend to `vlc -I rc` in order to show currently playing song
|
12
|
+
- Update command option `--count` to accept `-1` as a valid value for fetching all radio stations
|
13
|
+
- Make app fetch all radio stations by default (`--count -1`)
|
14
|
+
- Fix issue with bookmark/unbookmark menu items remaining enabled after stopping song
|
15
|
+
|
3
16
|
## 0.0.5
|
4
17
|
|
5
18
|
- Upgrade to glimmer-dsl-libui v0.5.22
|
@@ -7,6 +20,9 @@
|
|
7
20
|
- View menu with "All", "Bookmarks", and "Playing" View menu items
|
8
21
|
- Command option `--[no-]bookmarks` to show/hide bookmarks in table
|
9
22
|
- Command option `--[no-]gradual` to load radio stations gradually (preventing user from waiting for app to start) or avoid loading gradually
|
23
|
+
- Support AND-based filtering with multiple words separated by space treated as WORD1 AND WORD2, ...
|
24
|
+
- Support exact term filtering with double-quoted filter term (e.g. "WORD1 WORD2")
|
25
|
+
- Support column-based filtering by prefixing a query term with column name + colon (e.g. "language:english"), which can be combined with other words (e.g. "jazz language:english"). Also, there is no need to enter all of the column letters, yet only the first few letters that distinguish it from other columns (e.g. "jazz l:english")
|
10
26
|
|
11
27
|
## 0.0.4
|
12
28
|
|
data/README.md
CHANGED
@@ -1,17 +1,9 @@
|
|
1
1
|
# rubio-radio
|
2
2
|
[](https://badge.fury.io/rb/rubio-radio)
|
3
3
|
|
4
|
-
Linux
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
Mac
|
9
|
-
|
10
|
-

|
11
|
-
|
12
|
-
Windows
|
13
|
-
|
14
|
-

|
4
|
+
| Mac | Linux | Windows |
|
5
|
+
|:---:|:-----:|:-------:|
|
6
|
+
||||
|
15
7
|
|
16
8
|
:bowtie: Alpha
|
17
9
|
|
@@ -21,7 +13,7 @@ Windows
|
|
21
13
|
|
22
14
|
**[VLC](https://github.com/videolan/vlc)**
|
23
15
|
|
24
|
-
`rubio` uses the `vlc -I
|
16
|
+
`rubio` uses the `vlc -I rc` as the audio playback backend.
|
25
17
|
|
26
18
|
On Mac, it is recommended that you install VLC via [Homebrew](https://brew.sh/) to ensure the `vlc` command is added to the PATH environment variable automatically:
|
27
19
|
|
@@ -45,7 +37,7 @@ Run with this command:
|
|
45
37
|
rubio
|
46
38
|
```
|
47
39
|
|
48
|
-
|
40
|
+
All [Radio Browser](https://www.radio-browser.info/) stations are displayed by default. But, you can customize the count with `--count COUNT` (note that currently, there are only about 33,000 [Radio Browser](https://www.radio-browser.info/) stations total). Setting the count to `-1` will fetch all stations.
|
49
41
|
|
50
42
|
```
|
51
43
|
rubio --count 20000
|
@@ -57,7 +49,7 @@ The stations are fetched gradually (asynchronously) from the [Radio Browser](htt
|
|
57
49
|
rubio --no-gradual
|
58
50
|
```
|
59
51
|
|
60
|
-
Default player is `vlc -I
|
52
|
+
Default player is `vlc -I rc`, which enables showing currently playing song info (except on Windows). But, you can use any command line player that can take URL of radio station as its first argument.
|
61
53
|
|
62
54
|
```
|
63
55
|
rubio --backend mpg123
|
@@ -71,10 +63,10 @@ rubio --help
|
|
71
63
|
|
72
64
|
```
|
73
65
|
Usage: rubio [options]
|
74
|
-
--vlc [STR] use VLC interface STR on the backend [
|
66
|
+
--vlc [STR] use VLC interface STR on the backend [rc]
|
75
67
|
--mpg123 use mpg123 on the backend
|
76
|
-
-b, --backend STR command to use as backend player ['vlc -I
|
77
|
-
-c, --count INT number of stations to fetch from radio-browser [
|
68
|
+
-b, --backend STR command to use as backend player ['vlc -I rc']
|
69
|
+
-c, --count INT number of stations to fetch from radio-browser or -1 to fetch them all [-1]
|
78
70
|
--per-page INT number of stations per page [20]
|
79
71
|
-w, --width INT main window width
|
80
72
|
-h, --height INT main window height
|
@@ -82,6 +74,8 @@ Usage: rubio [options]
|
|
82
74
|
--[no-]menu show/hide menu [true]
|
83
75
|
--[no-]bookmarks show/hide bookmarks [true]
|
84
76
|
--[no-]gradual gradually/non-gradually fetch stations [true]
|
77
|
+
--[no-]margins show/hide margins [true]
|
78
|
+
--[no-]info show/hide currently playing (song) info when using 'vlc -I rc' backend only [true]
|
85
79
|
--debug output status of monitored threads
|
86
80
|
--help show this help message
|
87
81
|
--version show the rubio version number
|
@@ -90,15 +84,15 @@ Usage: rubio [options]
|
|
90
84
|
Examples:
|
91
85
|
|
92
86
|
```
|
93
|
-
rubio --vlc
|
94
|
-
rubio --mpg123 #
|
87
|
+
rubio --vlc dummy # vlc -I dummy (interactive command line interface)
|
88
|
+
rubio --mpg123 # rubio --backend mpg123
|
95
89
|
rubio --count 1000 # Displays the top 1,000 Radio Browser stations
|
96
90
|
```
|
97
91
|
|
98
92
|
Minimalistic Example:
|
99
93
|
|
100
94
|
```
|
101
|
-
rubio --per-page 6 --no-menu --no-bookmarks
|
95
|
+
rubio --per-page 6 --no-margins --no-info --no-menu --no-bookmarks
|
102
96
|
```
|
103
97
|
|
104
98
|

|
@@ -111,13 +105,53 @@ rubio --page-count
|
|
111
105
|
|
112
106
|

|
113
107
|
|
108
|
+
### Filtering
|
109
|
+
|
110
|
+
The filter field does AND-based filtering when you enter multiple words separated by spaces:
|
111
|
+
|
112
|
+
```
|
113
|
+
jazz smooth
|
114
|
+
```
|
115
|
+
|
116
|
+
Also, the filter field supports exact term filtering if you enter multiple words surrounded by double-quotes.
|
117
|
+
|
118
|
+
```
|
119
|
+
"bossa nova"
|
120
|
+
```
|
121
|
+
|
122
|
+
Last but not least, the filter field supports column-specific queries by including a full column name or the first few letters, followed by colon (:), followed by a single word or double-quoted multiple words for exact term matching against the column:
|
123
|
+
|
124
|
+
```
|
125
|
+
name:talk language:eng
|
126
|
+
```
|
127
|
+
|
128
|
+
or just:
|
129
|
+
|
130
|
+
```
|
131
|
+
n:talk l:eng
|
132
|
+
```
|
133
|
+
|
134
|
+

|
135
|
+
|
136
|
+
This advanced example matches the word `FM` against the name column, and language `bahasa indonesia` against the language column.
|
137
|
+
|
138
|
+
```
|
139
|
+
n:FM l:"bahasa indonesia"
|
140
|
+
```
|
141
|
+
|
142
|
+
Finally, you can mix different types of filters:
|
143
|
+
|
144
|
+
```
|
145
|
+
brasil "bossa jazz" l:brazilian l:portuguese
|
146
|
+
```
|
147
|
+
|
114
148
|
### Menus
|
115
149
|
|
116
150
|
You can use the top menu bar to stop the currently playing radio station, bookmark, unbookmark, view only bookmarked stations, view only currently playing station, and read the about dialog.
|
117
151
|
|
118
152
|

|
119
153
|
|
120
|
-
Bookmarks are stored in
|
154
|
+
Bookmarks are stored in `~/.rubio-radio/bookmarks.yml`
|
121
155
|
|
122
156
|
## Links
|
123
157
|
|
data/TODO.md
CHANGED
@@ -1,9 +1,3 @@
|
|
1
1
|
# TODO
|
2
2
|
|
3
|
-
|
4
|
-
- Support exact FTS (Full-Text-Search) queries using double-quotes (e.g. "WORD1 WORD2")
|
5
|
-
- Support column-based queries by prefixing query term with column name + colon (e.g. "language:english"), which can be combined with FTS queries (e.g. "jazz language:english"). Also, there is no need to enter all of the column letters, yet only the first few letters that distinguish it from other columns (e.g. "jazz l:english")
|
6
|
-
|
7
|
-
- Make window margined and provide option to disable margins if preferred (`--no-margins`)
|
8
|
-
|
9
|
-
- Show current playing song (use `vlc -I dummy --extraintf http --http-host localhost --http-port 9877 --http-password pass1234` backend, and then make an HTTP request to http://localhost:9877/requests/status.xml in order to obtain song information and update it every second; maybe regenerate a new password on every run) (alternatively, I can use backend `vlc -I rc` and call `info` to obtain song details, parsing the text after `now_playing:` .... can use `io = IO.popen('vlc -I rc http://radio.canstream.co.uk:8075/live.mp3', 'r+')` with `io.puts('inf')` and `io.gets` until all input is done; also use `Timeout::timeout(0.5) {}` to avoid timing out on `gets` when there is no more input)
|
3
|
+
N/A
|
data/exe/rubio
CHANGED
@@ -5,19 +5,20 @@ require 'puts_debuggerer' if ENV['PD'].to_s.downcase == 'true'
|
|
5
5
|
require 'rubio'
|
6
6
|
require 'optparse'
|
7
7
|
|
8
|
-
options = { backend: 'vlc -I
|
8
|
+
options = { backend: 'vlc -I rc' }
|
9
9
|
|
10
10
|
opt = OptionParser.new
|
11
11
|
opt.summary_width = 23
|
12
|
-
opt.on('--vlc [STR]', 'use VLC interface STR on the backend [
|
13
|
-
i ||= '
|
12
|
+
opt.on('--vlc [STR]', 'use VLC interface STR on the backend [rc]') do |i|
|
13
|
+
i ||= 'rc'
|
14
14
|
options[:backend] = "vlc -I #{i}"
|
15
15
|
end
|
16
16
|
opt.on('--mpg123', 'use mpg123 on the backend') { options[:backend] = 'mpg123' }
|
17
|
-
opt.on('-b', '--backend STR', String, 'command to use as backend player [\'vlc -I
|
17
|
+
opt.on('-b', '--backend STR', String, 'command to use as backend player [\'vlc -I rc\']') do |b|
|
18
18
|
options[:backend] = b
|
19
19
|
end
|
20
|
-
opt.on('-c', '--count INT', Numeric,
|
20
|
+
opt.on('-c', '--count INT', Numeric,
|
21
|
+
'number of stations to fetch from radio-browser or -1 to fetch them all [-1]') do |c|
|
21
22
|
options[:radio_station_count] = c
|
22
23
|
end
|
23
24
|
opt.on('--per-page INT', Numeric, 'number of stations per page [20]') { |c| options[:table_per_page] = c }
|
@@ -29,6 +30,11 @@ opt.on('--[no-]bookmarks', TrueClass, 'show/hide bookmarks [true]') { |b| option
|
|
29
30
|
opt.on('--[no-]gradual', TrueClass, 'gradually/non-gradually fetch stations [true]') do |g|
|
30
31
|
options[:gradually_fetch_stations] = g
|
31
32
|
end
|
33
|
+
opt.on('--[no-]margins', TrueClass, 'show/hide margins [true]') { |m| options[:show_margins] = m }
|
34
|
+
opt.on('--[no-]info', TrueClass,
|
35
|
+
'show/hide currently playing (song) info when using \'vlc -I rc\' backend only [true]') do |i|
|
36
|
+
options[:show_currently_playing] = i
|
37
|
+
end
|
32
38
|
opt.on('--debug', 'output status of monitored threads') { options[:debug] = true }
|
33
39
|
opt.on('--help', 'show this help message') do
|
34
40
|
puts opt
|
@@ -49,7 +55,7 @@ end
|
|
49
55
|
|
50
56
|
begin
|
51
57
|
Rubio::View::Radio.launch(**options)
|
52
|
-
rescue
|
53
|
-
Rubio::View::Radio.launched_application&.player&.stop_all
|
58
|
+
rescue => e
|
59
|
+
Rubio::View::Radio.launched_application&.presenter&.player&.stop_all
|
54
60
|
raise e
|
55
61
|
end
|
data/lib/rubio/model/bookmark.rb
CHANGED
@@ -33,7 +33,7 @@ module Rubio
|
|
33
33
|
def save_all
|
34
34
|
bookmarks_yaml = YAML.dump(all)
|
35
35
|
File.write(FILE_RUBIO_RADIO_BOOKMARKS, bookmarks_yaml)
|
36
|
-
rescue
|
36
|
+
rescue => e
|
37
37
|
puts 'Failed in saving bookmarks!'
|
38
38
|
puts all.inspect
|
39
39
|
puts e.full_message
|
@@ -43,7 +43,7 @@ module Rubio
|
|
43
43
|
def load_all
|
44
44
|
bookmarks_yaml = File.read(FILE_RUBIO_RADIO_BOOKMARKS)
|
45
45
|
YAML.load(bookmarks_yaml)
|
46
|
-
rescue
|
46
|
+
rescue => e
|
47
47
|
puts 'Failed in loading bookmarks! Returning empty bookmarks.'
|
48
48
|
puts e.full_message
|
49
49
|
[]
|
data/lib/rubio/model/player.rb
CHANGED
@@ -3,29 +3,40 @@
|
|
3
3
|
module Rubio
|
4
4
|
module Model
|
5
5
|
class Player
|
6
|
+
CURRENTLY_PLAYING_NONE = 'None'
|
7
|
+
CURRENTLY_PLAYING_LENGTH_PER_LINE = 90
|
8
|
+
|
6
9
|
attr_accessor :backend, :pid, :thr, :status, :history
|
10
|
+
attr_reader :show_currently_playing, :currently_playing
|
11
|
+
alias show_currently_playing? show_currently_playing
|
7
12
|
|
8
|
-
def initialize(backend =
|
13
|
+
def initialize(backend = 'vlc -I rc', show_currently_playing: true)
|
9
14
|
raise unless backend.is_a?(String)
|
10
15
|
|
11
16
|
@backend = backend
|
17
|
+
@show_currently_playing = show_currently_playing
|
12
18
|
@pid = nil
|
13
19
|
@thr = nil
|
14
|
-
@status =
|
20
|
+
@status = {}
|
15
21
|
@history = []
|
22
|
+
self.currently_playing = CURRENTLY_PLAYING_NONE
|
16
23
|
end
|
17
24
|
|
18
|
-
def
|
19
|
-
|
25
|
+
def currently_playing=(value)
|
26
|
+
value = "Playing: #{value}"
|
20
27
|
|
21
|
-
@
|
28
|
+
@currently_playing = break_by_lines(value)
|
29
|
+
end
|
30
|
+
|
31
|
+
def alive?
|
32
|
+
@thr&.alive? || (@io && !@io.closed?)
|
22
33
|
end
|
23
34
|
|
24
35
|
def stop?
|
25
36
|
@thr.nil? || @thr.stop?
|
26
37
|
end
|
27
38
|
|
28
|
-
def play(url)
|
39
|
+
def play(url, station_name: 'N/A')
|
29
40
|
# Do not include spaces in the command line
|
30
41
|
# if a space exist :
|
31
42
|
# * sh -c command url # this process with @pid will be killed
|
@@ -34,25 +45,114 @@ module Rubio
|
|
34
45
|
# * cmmand url # will be killed by @pid
|
35
46
|
raise if url.match(/\s/)
|
36
47
|
|
37
|
-
@
|
38
|
-
|
39
|
-
|
48
|
+
@playing_station_name = station_name
|
49
|
+
|
50
|
+
if show_currently_playing? && backend == 'vlc -I rc' && !OS.windows?
|
51
|
+
@io = IO.popen("#{backend} \"#{url}\"", 'r+')
|
52
|
+
update_currently_playing
|
53
|
+
continuously_fetch_currently_playing
|
54
|
+
else
|
55
|
+
@pid = spawn(*backend.split(' '), url)
|
56
|
+
@thr = Process.detach(@pid)
|
57
|
+
end
|
58
|
+
|
59
|
+
@status = { thr: @thr, pid: @pid, io: @io }
|
40
60
|
@history << @status
|
41
61
|
end
|
42
62
|
|
43
|
-
def
|
44
|
-
return
|
63
|
+
def continuously_fetch_currently_playing
|
64
|
+
return if @continuously_fetching_currently_playing
|
45
65
|
|
46
|
-
|
47
|
-
|
48
|
-
|
66
|
+
@continuously_fetching_currently_playing = true
|
67
|
+
|
68
|
+
Glimmer::LibUI.timer(1) do
|
69
|
+
update_currently_playing
|
70
|
+
@continuously_fetching_currently_playing
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def update_currently_playing
|
75
|
+
Glimmer::LibUI.queue_main do
|
76
|
+
self.currently_playing = currently_playing_text if alive?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def currently_playing_text
|
81
|
+
currently_playing_info = info
|
82
|
+
if currently_playing_info && !currently_playing_info.strip.empty?
|
83
|
+
[@playing_station_name, currently_playing_info].join(' - ')
|
84
|
+
else
|
85
|
+
@playing_station_name
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def info
|
90
|
+
result = io_command('info')
|
91
|
+
now_playing_line = result.lines.find {|l| l.include?('now_playing:')}
|
92
|
+
if now_playing_line
|
93
|
+
now_playing_line.split('now_playing:').last.chomp.strip
|
94
|
+
end
|
95
|
+
rescue
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def stop(thr: nil, pid: nil, io: nil)
|
100
|
+
thr ||= @thr
|
101
|
+
pid ||= @pid
|
102
|
+
io ||= @io
|
103
|
+
if thr&.alive?
|
104
|
+
r = Process.kill(OS.windows? ? :KILL : :TERM, pid)
|
105
|
+
elsif io && !io.closed?
|
106
|
+
io.close
|
107
|
+
r = io.closed?
|
108
|
+
self.currently_playing = CURRENTLY_PLAYING_NONE
|
109
|
+
end
|
110
|
+
thr = nil
|
111
|
+
pid = nil
|
112
|
+
io = nil
|
49
113
|
r
|
50
114
|
end
|
51
115
|
|
52
116
|
def stop_all
|
53
|
-
@
|
54
|
-
|
117
|
+
@continuously_fetching_currently_playing = false
|
118
|
+
@history.each { |history| stop(**history) }
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def break_by_lines(text, length_per_line: CURRENTLY_PLAYING_LENGTH_PER_LINE)
|
124
|
+
new_text_lines = ['']
|
125
|
+
text.chars.each_with_index do |char, i|
|
126
|
+
if (char != ' ' && new_text_lines[-1].length < length_per_line - 1) ||
|
127
|
+
(char == ' ' && new_text_lines[-1].length < length_per_line)
|
128
|
+
new_text_lines[-1] = new_text_lines[-1] + char
|
129
|
+
else
|
130
|
+
new_text_lines[-1] = new_text_lines[-1] + '-' if new_text_lines[-1][-1] != ' '
|
131
|
+
new_text_lines << char
|
132
|
+
end
|
133
|
+
end
|
134
|
+
new_text_lines.join("\n")
|
135
|
+
end
|
136
|
+
|
137
|
+
def io_command(command)
|
138
|
+
@io.puts(command)
|
139
|
+
io_all_gets
|
140
|
+
end
|
141
|
+
|
142
|
+
def io_all_gets
|
143
|
+
result = ''
|
144
|
+
while gets_result = io_gets
|
145
|
+
result += gets_result.to_s
|
146
|
+
end
|
147
|
+
result
|
148
|
+
end
|
149
|
+
|
150
|
+
def io_gets
|
151
|
+
Timeout.timeout(0.01) do
|
152
|
+
@io.gets
|
55
153
|
end
|
154
|
+
rescue
|
155
|
+
nil
|
56
156
|
end
|
57
157
|
end
|
58
158
|
end
|
@@ -19,7 +19,7 @@ module Rubio
|
|
19
19
|
content = URI.parse(base_url + "stations/topvote/#{n}?offset=#{offset}")
|
20
20
|
result = []
|
21
21
|
JSON[content.read].each_with_index do |s, _i|
|
22
|
-
result << Station.new(s['stationuuid'], s['name'], s['language'], s['url_resolved'])
|
22
|
+
result << Station.new(s['stationuuid'], s['name'], s['language'], s['country'], s['url_resolved'])
|
23
23
|
end
|
24
24
|
result
|
25
25
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../model/radio_browser'
|
4
|
+
require_relative '../model/player'
|
5
|
+
|
6
|
+
module Rubio
|
7
|
+
module Model
|
8
|
+
# This is a presenter for the Radio view, which is an advanced controller
|
9
|
+
class RadioPresenter
|
10
|
+
attr_reader :player, :initial_width, :initial_height, :options
|
11
|
+
attr_accessor :stations, :current_station, :view, :window_height
|
12
|
+
|
13
|
+
# Initializes with view options below:
|
14
|
+
# :backend, :initial_width, :initial_height, :radio_station_count, :debug,
|
15
|
+
# :show_menu, :show_page_count, :show_bookmarks, :show_margins
|
16
|
+
# :gradually_fetch_stations, :table_per_page
|
17
|
+
def initialize(options = {})
|
18
|
+
@options = options
|
19
|
+
@options[:radio_station_count] = 1_000_000 if options[:radio_station_count] == -1
|
20
|
+
@loaded_station_count = [options[:gradually_fetch_stations] ? 100 : options[:radio_station_count], options[:radio_station_count]].min
|
21
|
+
@loaded_station_offset = 0
|
22
|
+
@stations = Model::RadioBrowser.topvote(@loaded_station_count, offset: @loaded_station_offset)
|
23
|
+
@player = Model::Player.new(options[:backend], show_currently_playing: options[:show_currently_playing])
|
24
|
+
@initial_width = (options[:initial_width] || (options[:show_bookmarks] ? 740 : 620)).to_i
|
25
|
+
@initial_height = (options[:initial_height] || calculate_initial_height).to_i
|
26
|
+
@window_height = @initial_height
|
27
|
+
@view = :all
|
28
|
+
|
29
|
+
Glimmer::DataBinding::Observer::Proc.new do
|
30
|
+
self.window_height = calculate_initial_height
|
31
|
+
end.observe(@player, :currently_playing)
|
32
|
+
end
|
33
|
+
|
34
|
+
def select_station(station)
|
35
|
+
playing = station.playing?
|
36
|
+
stop_station
|
37
|
+
self.current_station = station
|
38
|
+
if playing
|
39
|
+
self.current_station = nil
|
40
|
+
else
|
41
|
+
play_station
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def toggle_bookmarked_station(station)
|
46
|
+
return unless station
|
47
|
+
|
48
|
+
station.bookmarked = !station.bookmarked?
|
49
|
+
end
|
50
|
+
|
51
|
+
def play_station
|
52
|
+
@player.play(current_station.url, station_name: current_station.name)
|
53
|
+
current_station.playing = true
|
54
|
+
rescue => e
|
55
|
+
self.current_station = nil
|
56
|
+
raise e
|
57
|
+
end
|
58
|
+
|
59
|
+
def stop_station
|
60
|
+
return if current_station.nil?
|
61
|
+
|
62
|
+
@player.stop
|
63
|
+
current_station.playing = false
|
64
|
+
self.current_station = nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def stations_incomplete?
|
68
|
+
!@all_stations_fetched && @stations.count < options[:radio_station_count]
|
69
|
+
end
|
70
|
+
|
71
|
+
def fetch_more_stations
|
72
|
+
@loaded_station_offset += @loaded_station_count
|
73
|
+
@loaded_station_count *= 2
|
74
|
+
new_station_count = [@loaded_station_count, options[:radio_station_count] - @loaded_station_offset].min
|
75
|
+
old_station_count = @stations.count
|
76
|
+
self.stations += Model::RadioBrowser.topvote(new_station_count, offset: @loaded_station_offset)
|
77
|
+
@all_stations_fetched = @stations.count == old_station_count
|
78
|
+
self.stations
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def calculate_initial_height
|
84
|
+
window_margin = options[:show_margins] ? (OS.linux? ? 22 : 40) : 0
|
85
|
+
currently_playing_height = options[:show_currently_playing] ? ((@player.currently_playing ? @player.currently_playing.lines.size : 1)*16 + 8) : 0
|
86
|
+
table_per_page = options[:table_per_page].to_i
|
87
|
+
if OS.linux?
|
88
|
+
108 + window_margin + currently_playing_height + (options[:show_menu] ? 26 : 0) + 24 * table_per_page
|
89
|
+
elsif OS.mac? && OS.host_cpu == 'arm64'
|
90
|
+
90 + window_margin + currently_playing_height + 24 * table_per_page
|
91
|
+
elsif OS.mac?
|
92
|
+
85 + window_margin + currently_playing_height + 19 * table_per_page
|
93
|
+
else # Windows
|
94
|
+
95 + window_margin + currently_playing_height + 19 * table_per_page
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/rubio/model/station.rb
CHANGED
@@ -4,7 +4,7 @@ require_relative 'bookmark'
|
|
4
4
|
|
5
5
|
module Rubio
|
6
6
|
module Model
|
7
|
-
Station = Struct.new(:stationuuid, :name, :language, :url, :play, :bookmark) do
|
7
|
+
Station = Struct.new(:stationuuid, :name, :language, :country, :url, :play, :bookmark) do
|
8
8
|
attr_reader :playing, :bookmarked
|
9
9
|
alias_method :playing?, :playing
|
10
10
|
alias_method :bookmarked?, :bookmarked
|
data/lib/rubio/version.rb
CHANGED
data/lib/rubio/view/radio.rb
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'glimmer-dsl-libui'
|
4
4
|
|
5
|
-
require_relative '../model/
|
6
|
-
require_relative '../model/player'
|
5
|
+
require_relative '../model/radio_presenter'
|
7
6
|
|
8
7
|
module Rubio
|
9
8
|
module View
|
@@ -11,49 +10,60 @@ module Rubio
|
|
11
10
|
include Glimmer::LibUI::Application
|
12
11
|
|
13
12
|
options :backend, :initial_width, :initial_height
|
14
|
-
option :radio_station_count, default:
|
13
|
+
option :radio_station_count, default: -1
|
15
14
|
option :debug, default: false
|
16
15
|
option :show_menu, default: true
|
17
16
|
option :show_page_count, default: false
|
18
17
|
option :show_bookmarks, default: true
|
18
|
+
option :show_margins, default: true
|
19
|
+
option :show_currently_playing, default: true
|
19
20
|
option :gradually_fetch_stations, default: true
|
20
21
|
option :table_per_page, default: 20
|
21
22
|
|
22
|
-
attr_reader :
|
23
|
-
attr_accessor :current_station, :view
|
23
|
+
attr_reader :presenter
|
24
24
|
|
25
25
|
before_body do
|
26
|
-
|
27
|
-
@
|
28
|
-
@stations = Model::RadioBrowser.topvote(@loaded_station_count, offset: @loaded_station_offset)
|
29
|
-
@player = Model::Player.new(backend)
|
30
|
-
@initial_width = (initial_width || (show_bookmarks ? 740 : 620)).to_i
|
31
|
-
@initial_height = (initial_height || calculate_initial_height).to_i
|
32
|
-
@view = :all
|
26
|
+
# options is a method on Glimmer::LibUI::Application that contains all options declared above
|
27
|
+
@presenter = Model::RadioPresenter.new(options)
|
33
28
|
end
|
34
29
|
|
35
30
|
after_body do
|
36
31
|
monitor_thread(debug)
|
37
|
-
async_fetch_stations if gradually_fetch_stations && @
|
32
|
+
async_fetch_stations if gradually_fetch_stations && @presenter.stations_incomplete?
|
38
33
|
end
|
39
34
|
|
40
35
|
body do
|
41
36
|
radio_menu_bar
|
42
37
|
|
43
|
-
window('Rubio', @initial_width, @initial_height) do
|
38
|
+
window('Rubio', @presenter.initial_width, @presenter.initial_height / (OS.linux? ? 2.0 : 1)) do
|
39
|
+
margined show_margins
|
40
|
+
height <= [@presenter, :window_height,
|
41
|
+
on_read: ->(value) {
|
42
|
+
w = body_root
|
43
|
+
if w.nil? # window not built yet
|
44
|
+
# Linux libui is weird. The first time height is set, it must be halved
|
45
|
+
value / (OS.linux? ? 2.0 : 1)
|
46
|
+
else
|
47
|
+
value -= 50 if OS.linux? # more Linux weirdness
|
48
|
+
value = value > w.height ? value : w.height # grow only, never shrink
|
49
|
+
value
|
50
|
+
end
|
51
|
+
}
|
52
|
+
]
|
53
|
+
|
44
54
|
vertical_box do
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
55
|
+
currently_playing_label
|
56
|
+
|
57
|
+
@station_table = refined_table(
|
58
|
+
table_columns: station_table_columns,
|
59
|
+
model_array: @presenter.stations,
|
60
|
+
per_page: table_per_page.to_i,
|
61
|
+
visible_page_count: show_page_count
|
62
|
+
)
|
53
63
|
end
|
54
64
|
|
55
65
|
on_closing do
|
56
|
-
@player.stop_all
|
66
|
+
@presenter.player.stop_all
|
57
67
|
end
|
58
68
|
end
|
59
69
|
end
|
@@ -69,28 +79,28 @@ module Rubio
|
|
69
79
|
def radio_menu
|
70
80
|
menu('Radio') do
|
71
81
|
menu_item('Stop') do
|
72
|
-
enabled <= [
|
73
|
-
|
82
|
+
enabled <= [@presenter, 'current_station', on_read: ->(value) { !!value }]
|
83
|
+
|
74
84
|
on_clicked do
|
75
|
-
stop_station
|
85
|
+
@presenter.stop_station
|
76
86
|
end
|
77
87
|
end
|
78
88
|
|
79
89
|
separator_menu_item
|
80
90
|
|
81
91
|
menu_item('Bookmark') do
|
82
|
-
enabled <= [
|
83
|
-
|
92
|
+
enabled <= [@presenter, 'current_station.bookmarked', on_read: ->(value) { value == false }]
|
93
|
+
|
84
94
|
on_clicked do
|
85
|
-
toggle_bookmarked_station
|
95
|
+
toggle_bookmarked_station
|
86
96
|
end
|
87
97
|
end
|
88
98
|
|
89
99
|
menu_item('Unbookmark') do
|
90
|
-
enabled <= [
|
91
|
-
|
100
|
+
enabled <= [@presenter, 'current_station.bookmarked', on_read: ->(value) { value == true }]
|
101
|
+
|
92
102
|
on_clicked do
|
93
|
-
toggle_bookmarked_station
|
103
|
+
toggle_bookmarked_station
|
94
104
|
end
|
95
105
|
end
|
96
106
|
|
@@ -106,7 +116,7 @@ module Rubio
|
|
106
116
|
|
107
117
|
quit_menu_item do
|
108
118
|
on_clicked do
|
109
|
-
@player.stop_all
|
119
|
+
@presenter.player.stop_all
|
110
120
|
end
|
111
121
|
end
|
112
122
|
end
|
@@ -115,30 +125,33 @@ module Rubio
|
|
115
125
|
def view_menu
|
116
126
|
menu('View') do
|
117
127
|
radio_menu_item('All') do
|
118
|
-
checked <=> [
|
119
|
-
|
120
|
-
|
121
|
-
|
128
|
+
checked <=> [@presenter, :view,
|
129
|
+
on_read: ->(value) { value == :all },
|
130
|
+
on_write: ->(value) { :all },
|
131
|
+
]
|
132
|
+
|
122
133
|
on_clicked do
|
123
134
|
view_all
|
124
135
|
end
|
125
136
|
end
|
126
137
|
|
127
138
|
radio_menu_item('Bookmarks') do
|
128
|
-
checked <=> [
|
129
|
-
|
130
|
-
|
131
|
-
|
139
|
+
checked <=> [@presenter, :view,
|
140
|
+
on_read: ->(value) { value == :bookmarks },
|
141
|
+
on_write: ->(value) { :bookmarks },
|
142
|
+
]
|
143
|
+
|
132
144
|
on_clicked do
|
133
145
|
view_bookmarks
|
134
146
|
end
|
135
147
|
end
|
136
148
|
|
137
149
|
radio_menu_item('Playing') do
|
138
|
-
checked <=> [
|
139
|
-
|
140
|
-
|
141
|
-
|
150
|
+
checked <=> [@presenter, :view,
|
151
|
+
on_read: ->(value) { value == :playing },
|
152
|
+
on_write: ->(value) { :playing },
|
153
|
+
]
|
154
|
+
|
142
155
|
on_clicked do
|
143
156
|
view_playing
|
144
157
|
end
|
@@ -158,13 +171,27 @@ module Rubio
|
|
158
171
|
end
|
159
172
|
end
|
160
173
|
|
174
|
+
def currently_playing_label
|
175
|
+
return unless show_currently_playing && backend == 'vlc -I rc' && !OS.windows?
|
176
|
+
|
177
|
+
label do
|
178
|
+
stretchy false
|
179
|
+
text <= [@presenter.player, :currently_playing]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
161
183
|
def station_table_columns
|
162
184
|
table_columns = {
|
163
185
|
'Play' => {
|
164
186
|
button: {
|
165
187
|
on_clicked: lambda { |row|
|
166
188
|
station = @station_table.refined_model_array[row]
|
167
|
-
|
189
|
+
begin
|
190
|
+
@presenter.select_station(station)
|
191
|
+
rescue => e
|
192
|
+
puts e.full_message if debug
|
193
|
+
message_box(e.message)
|
194
|
+
end
|
168
195
|
}
|
169
196
|
}
|
170
197
|
}
|
@@ -185,66 +212,42 @@ module Rubio
|
|
185
212
|
|
186
213
|
table_columns.merge!(
|
187
214
|
'name' => :text,
|
188
|
-
'language' => :text
|
215
|
+
'language' => :text,
|
216
|
+
'country' => :text
|
189
217
|
)
|
190
218
|
end
|
191
219
|
|
192
220
|
def about_message_box
|
193
221
|
license = begin
|
194
222
|
File.read(File.expand_path('../../../LICENSE.txt', __dir__))
|
195
|
-
rescue
|
223
|
+
rescue => e
|
224
|
+
puts e.full_message if debug
|
196
225
|
''
|
197
226
|
end
|
198
227
|
product = "rubio-radio #{Rubio::VERSION}"
|
199
228
|
message_box(product, "#{product}\n\n#{license}")
|
200
229
|
end
|
201
230
|
|
202
|
-
def
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
if playing
|
207
|
-
self.current_station = nil
|
208
|
-
else
|
209
|
-
play_station
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def toggle_bookmarked_station(station)
|
214
|
-
station.bookmarked = !station.bookmarked?
|
215
|
-
view_bookmarks if view == :bookmarks && !station.bookmarked
|
216
|
-
end
|
217
|
-
|
218
|
-
def play_station
|
219
|
-
@player.play(current_station.url)
|
220
|
-
current_station.playing = true
|
221
|
-
rescue StandardError => e
|
222
|
-
message_box(e.message)
|
223
|
-
self.current_station = nil
|
224
|
-
end
|
225
|
-
|
226
|
-
def stop_station
|
227
|
-
return if current_station.nil?
|
228
|
-
|
229
|
-
@player.stop
|
230
|
-
current_station.playing = false
|
231
|
-
self.current_station = nil
|
231
|
+
def toggle_bookmarked_station(station = nil)
|
232
|
+
station ||= @presenter.current_station
|
233
|
+
@presenter.toggle_bookmarked_station(station)
|
234
|
+
view_bookmarks if @presenter.view == :bookmarks && !station.bookmarked
|
232
235
|
end
|
233
236
|
|
234
237
|
def view_all
|
235
|
-
@station_table.model_array = stations
|
238
|
+
@station_table.model_array = @presenter.stations
|
236
239
|
end
|
237
240
|
|
238
241
|
def view_bookmarks
|
239
|
-
@station_table.model_array = stations.select(&:bookmarked?)
|
242
|
+
@station_table.model_array = @presenter.stations.select(&:bookmarked?)
|
240
243
|
end
|
241
244
|
|
242
245
|
def view_playing
|
243
|
-
@station_table.model_array = stations.select(&:playing?)
|
246
|
+
@station_table.model_array = @presenter.stations.select(&:playing?)
|
244
247
|
end
|
245
248
|
|
246
249
|
def refresh_view
|
247
|
-
case view
|
250
|
+
case @presenter.view
|
248
251
|
when :all
|
249
252
|
view_all
|
250
253
|
when :bookmarks
|
@@ -256,39 +259,24 @@ module Rubio
|
|
256
259
|
|
257
260
|
private
|
258
261
|
|
259
|
-
def calculate_initial_height
|
260
|
-
if OS.linux?
|
261
|
-
107 + (show_menu ? 26 : 0) + 24 * table_per_page.to_i
|
262
|
-
elsif OS.mac? && OS.host_cpu == 'arm64'
|
263
|
-
90 + 24 * table_per_page.to_i
|
264
|
-
elsif OS.mac?
|
265
|
-
85 + 19 * table_per_page.to_i
|
266
|
-
else # Windows
|
267
|
-
95 + 19 * table_per_page.to_i
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
262
|
def monitor_thread(debug)
|
272
263
|
Glimmer::LibUI.timer(1) do
|
273
|
-
p @player.history if debug
|
274
|
-
next if current_station.nil? || @player.alive?
|
264
|
+
p @presenter.player.history if debug
|
265
|
+
next if @presenter.current_station.nil? || @presenter.player.alive?
|
275
266
|
|
276
|
-
message_box("player '#{@player.backend}' stopped!", @player.thr.to_s)
|
277
|
-
stop_station
|
267
|
+
message_box("player '#{@presenter.player.backend}' stopped!", @presenter.player.thr.to_s)
|
268
|
+
@presenter.stop_station
|
278
269
|
true
|
279
270
|
end
|
280
271
|
end
|
281
272
|
|
282
273
|
def async_fetch_stations
|
283
|
-
@loaded_station_offset += @loaded_station_count
|
284
|
-
@loaded_station_count *= 2
|
285
274
|
Thread.new do
|
286
|
-
|
287
|
-
@stations += Model::RadioBrowser.topvote(new_station_count, offset: @loaded_station_offset)
|
275
|
+
@presenter.fetch_more_stations
|
288
276
|
|
289
277
|
Glimmer::LibUI.queue_main do
|
290
278
|
refresh_view
|
291
|
-
async_fetch_stations if @
|
279
|
+
async_fetch_stations if @presenter.stations_incomplete?
|
292
280
|
end
|
293
281
|
end
|
294
282
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubio-radio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kojix2
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-01-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: glimmer-dsl-libui
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - '='
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0.5.
|
20
|
+
version: 0.5.24
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - '='
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 0.5.
|
27
|
+
version: 0.5.24
|
28
28
|
description: Rubio is a simple radio player written in Ruby.
|
29
29
|
email:
|
30
30
|
- 2xijok@gmail.com
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/rubio/model/bookmark.rb
|
43
43
|
- lib/rubio/model/player.rb
|
44
44
|
- lib/rubio/model/radio_browser.rb
|
45
|
+
- lib/rubio/model/radio_presenter.rb
|
45
46
|
- lib/rubio/model/station.rb
|
46
47
|
- lib/rubio/version.rb
|
47
48
|
- lib/rubio/view/radio.rb
|
@@ -64,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
65
|
- !ruby/object:Gem::Version
|
65
66
|
version: '0'
|
66
67
|
requirements: []
|
67
|
-
rubygems_version: 3.3.
|
68
|
+
rubygems_version: 3.3.26
|
68
69
|
signing_key:
|
69
70
|
specification_version: 4
|
70
71
|
summary: Rubio - A simple radio player
|