LOLastfm 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LOLastfm.gemspec +0 -1
- data/README.md +51 -2
- data/bin/LOLastfm +1 -1
- data/bin/LOLastfm-cmus +1 -1
- data/bin/LOLastfm-lyrics +22 -0
- data/bin/LOLastfm-now-playing +14 -0
- data/bin/{LOLastfm-do → LOLastfm-send} +20 -6
- data/lib/LOLastfm.rb +48 -17
- data/lib/LOLastfm/checker.rb +8 -4
- data/lib/LOLastfm/checkers/cmus.rb +19 -9
- data/lib/LOLastfm/checkers/moc.rb +60 -34
- data/lib/LOLastfm/commands/glyr.rb +21 -6
- data/lib/LOLastfm/connection.rb +5 -1
- data/lib/LOLastfm/song.rb +2 -0
- data/lib/LOLastfm/version.rb +1 -1
- metadata +8 -20
data/LOLastfm.gemspec
CHANGED
data/README.md
CHANGED
@@ -1,2 +1,51 @@
|
|
1
|
-
LOLastfm -
|
2
|
-
|
1
|
+
LOLastfm - LOL a scrobbler
|
2
|
+
==========================
|
3
|
+
LOLastfm is a modular and extensible last.fm scrobbler.
|
4
|
+
|
5
|
+
It supports a virtually infinite array of music players and has a cool server-client
|
6
|
+
interface that lets you manage music related features seamlessly.
|
7
|
+
|
8
|
+
For instance, you can ask it the current playing song without having to relay on client specific
|
9
|
+
shims, or by including the glyr extension you can ask it to give you the lyrics of the currently
|
10
|
+
playing song.
|
11
|
+
|
12
|
+
How to configure
|
13
|
+
----------------
|
14
|
+
Before being able to use LOLastfm you have to allow access to it on last.fm, just run `LOLastfm -a`
|
15
|
+
and follow what it says, then create a file at `~/.LOLastfm/config` and put the session id it gave you
|
16
|
+
back.
|
17
|
+
|
18
|
+
You have to then tell LOLastfm what music player you want to be used, you can do it dynamically with
|
19
|
+
`LOLastfm-do --use player:path'.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
session 'heregoesthesession'
|
23
|
+
|
24
|
+
use :moc
|
25
|
+
```
|
26
|
+
|
27
|
+
The example above is if you're using moc.
|
28
|
+
|
29
|
+
You can also hook to certain events to, for example, change the attributes of a song before it's sent.
|
30
|
+
|
31
|
+
This allows for some neat features, like easily scrobbling from a radio, the following example shows
|
32
|
+
how to scrobble songs from trance.fm.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
%w(listened love now_playing).each {|name|
|
36
|
+
on name do |song|
|
37
|
+
next if song.artist || !song.stream?
|
38
|
+
|
39
|
+
if song.comment && song.comment.include?('trance.fm')
|
40
|
+
next :stop if song.title.include?('trance.fm') || song.title.start_with?('Trance - FM-')
|
41
|
+
|
42
|
+
song.artist, song.title = song.title.split(/ - /, 2)
|
43
|
+
song.length = 60 * 1337
|
44
|
+
|
45
|
+
next
|
46
|
+
end
|
47
|
+
|
48
|
+
:stop
|
49
|
+
end
|
50
|
+
}
|
51
|
+
```
|
data/bin/LOLastfm
CHANGED
data/bin/LOLastfm-cmus
CHANGED
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
|
5
5
|
args = Hash[*ARGV]
|
6
6
|
|
7
|
-
UNIXSocket.new(File.expand_path('~/.LOLastfm
|
7
|
+
UNIXSocket.new(File.expand_path('~/.LOLastfm/socket')).tap {|socket|
|
8
8
|
if args['url']
|
9
9
|
socket.puts [:hint, [:stream, args['title'], args['comment']]].to_json
|
10
10
|
end
|
data/bin/LOLastfm-lyrics
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'json'
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
socket = UNIXSocket.new(File.expand_path(ARGV.empty? ? '~/.LOLastfm/socket' : ARGV.first))
|
6
|
+
socket.puts [:commands, :glyr].to_json
|
7
|
+
|
8
|
+
if STDOUT.tty?
|
9
|
+
require 'ncursesw'
|
10
|
+
|
11
|
+
abort 'ncurses UI not implemented yet, redirect the output to something'
|
12
|
+
else
|
13
|
+
socket.puts [:lyrics?].to_json
|
14
|
+
|
15
|
+
response = JSON.parse(socket.readline)
|
16
|
+
|
17
|
+
if response.first
|
18
|
+
puts response.first['data']
|
19
|
+
else
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'json'
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
socket = UNIXSocket.new(File.expand_path(ARGV.empty? ? '~/.LOLastfm/socket' : ARGV.first))
|
6
|
+
socket.puts [:now_playing?].to_json
|
7
|
+
|
8
|
+
response = JSON.parse(?[ + socket.readline + ?]).first
|
9
|
+
|
10
|
+
exit 1 if response.nil?
|
11
|
+
|
12
|
+
%w[track title artist album].each {|name|
|
13
|
+
puts "#{name} #{response[name]}" if response[name]
|
14
|
+
}
|
@@ -6,7 +6,7 @@ require 'json'
|
|
6
6
|
options = {}
|
7
7
|
|
8
8
|
OptionParser.new do |o|
|
9
|
-
options[:socket] = '~/.LOLastfm
|
9
|
+
options[:socket] = '~/.LOLastfm/socket'
|
10
10
|
options[:song] = {}
|
11
11
|
|
12
12
|
o.on '--listened', 'enable listened sending' do
|
@@ -48,6 +48,14 @@ OptionParser.new do |o|
|
|
48
48
|
o.on '-i', '--id ID', 'the MusicBrainz id of the song' do |value|
|
49
49
|
options[:song][:id] = value
|
50
50
|
end
|
51
|
+
|
52
|
+
o.on '-u', '--use USE', 'the string for the checker' do |value|
|
53
|
+
options[:use] = value
|
54
|
+
end
|
55
|
+
|
56
|
+
o.on '-u', '--commands COMMANDS', 'the string for the command library' do |value|
|
57
|
+
options[:commands] = value
|
58
|
+
end
|
51
59
|
end.parse!
|
52
60
|
|
53
61
|
if ARGV.first
|
@@ -56,12 +64,18 @@ end
|
|
56
64
|
|
57
65
|
socket = UNIXSocket.new(File.expand_path(options[:socket]))
|
58
66
|
|
59
|
-
if options[:
|
60
|
-
socket.puts [:
|
61
|
-
elsif options[:
|
62
|
-
socket.puts [:
|
67
|
+
if options[:use]
|
68
|
+
socket.puts [:use, options[:use].split(':')].to_json
|
69
|
+
elsif options[:commands]
|
70
|
+
socket.puts [:commands, options[:commands].split(':')].to_json
|
63
71
|
else
|
64
|
-
|
72
|
+
if options[:now_playing]
|
73
|
+
socket.puts [:now_playing, options[:song]].to_json
|
74
|
+
elsif options[:love]
|
75
|
+
socket.puts [:love, options[:song].empty? ? nil : options[:song]].to_json
|
76
|
+
else
|
77
|
+
socket.puts [:listened, options[:song]].to_json
|
78
|
+
end
|
65
79
|
end
|
66
80
|
|
67
81
|
socket.flush
|
data/lib/LOLastfm.rb
CHANGED
@@ -10,7 +10,6 @@
|
|
10
10
|
|
11
11
|
require 'eventmachine'
|
12
12
|
require 'lastfm'
|
13
|
-
require 'call-me/memoize'
|
14
13
|
|
15
14
|
class LOLastfm
|
16
15
|
def self.load (path)
|
@@ -33,31 +32,45 @@ class LOLastfm
|
|
33
32
|
commands[name.to_sym.downcase] = block
|
34
33
|
end
|
35
34
|
|
36
|
-
attr_reader :cache
|
35
|
+
attr_reader :path, :host, :port, :cache
|
37
36
|
|
38
37
|
def initialize
|
39
38
|
@session = Lastfm.new('5f7b134ba19b20536a5e29bc86ae64c9', '3b50e74d989795c3f4b3667c5a1c8e67')
|
40
39
|
@cache = Cache.new(self)
|
41
40
|
@events = Hash.new { |h, k| h[k] = [] }
|
42
41
|
|
43
|
-
cache_at '~/.LOLastfm
|
42
|
+
cache_at '~/.LOLastfm/cache'
|
44
43
|
end
|
45
44
|
|
46
45
|
def load (path)
|
47
46
|
instance_eval File.read(File.expand_path(path)), path
|
48
47
|
end
|
49
48
|
|
49
|
+
def started?; !!@started; end
|
50
|
+
|
50
51
|
def start
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
return if started?
|
53
|
+
|
54
|
+
@server = if @host && @port
|
55
|
+
EM.start_server(host, port, LOLastfm::Connection) {|conn|
|
56
|
+
conn.fm = self
|
57
|
+
}
|
58
|
+
else
|
59
|
+
EM.start_unix_domain_server(path || File.expand_path('~/.LOLastfm/socket'), LOLastfm::Connection) {|conn|
|
60
|
+
conn.fm = self
|
61
|
+
}
|
62
|
+
end
|
54
63
|
|
55
64
|
@timer = EM.add_periodic_timer 360 do
|
56
65
|
save
|
57
66
|
end
|
67
|
+
|
68
|
+
@checker.start
|
58
69
|
end
|
59
70
|
|
60
71
|
def stop
|
72
|
+
return unless started?
|
73
|
+
|
61
74
|
EM.stop_server @server
|
62
75
|
EM.cancel_timer @timer
|
63
76
|
|
@@ -82,8 +95,13 @@ class LOLastfm
|
|
82
95
|
end
|
83
96
|
end
|
84
97
|
|
85
|
-
def
|
86
|
-
|
98
|
+
def server_at (host, port = nil)
|
99
|
+
if port
|
100
|
+
@host = host
|
101
|
+
@port = port
|
102
|
+
else
|
103
|
+
@path = host
|
104
|
+
end
|
87
105
|
end
|
88
106
|
|
89
107
|
def session (key)
|
@@ -96,6 +114,7 @@ class LOLastfm
|
|
96
114
|
|
97
115
|
def now_playing (song)
|
98
116
|
song = Song.new(song) unless song.is_a?(Song)
|
117
|
+
song = song.dup
|
99
118
|
|
100
119
|
return false unless fire :now_playing, song
|
101
120
|
|
@@ -112,6 +131,7 @@ class LOLastfm
|
|
112
131
|
|
113
132
|
def listened (song)
|
114
133
|
song = Song.new(song) unless song.is_a?(Song)
|
134
|
+
song = song.dup
|
115
135
|
|
116
136
|
return false unless fire :listened, song
|
117
137
|
|
@@ -138,6 +158,7 @@ class LOLastfm
|
|
138
158
|
def love (song = nil)
|
139
159
|
song = @last_played or return unless song
|
140
160
|
song = Song.new(song) unless song.is_a? Song
|
161
|
+
song = song.dup
|
141
162
|
|
142
163
|
return false unless fire :love, song
|
143
164
|
|
@@ -168,16 +189,26 @@ class LOLastfm
|
|
168
189
|
@last_played
|
169
190
|
end
|
170
191
|
|
171
|
-
def
|
172
|
-
|
173
|
-
|
192
|
+
def commands (name)
|
193
|
+
begin
|
194
|
+
require "LOLastfm/commands/#{name}"
|
195
|
+
rescue LoadError
|
196
|
+
require name.to_s
|
174
197
|
end
|
198
|
+
end
|
175
199
|
|
176
|
-
|
200
|
+
def use (*args, &block)
|
201
|
+
return if args.empty? && !block
|
202
|
+
|
203
|
+
unless args.first.respond_to?(:to_hash) || block
|
177
204
|
name = args.shift.to_sym
|
178
205
|
|
179
|
-
if args.first.is_a?
|
180
|
-
require args.
|
206
|
+
if args.first.is_a? String
|
207
|
+
require args.pop
|
208
|
+
elsif !self.class.checkers[name]
|
209
|
+
begin
|
210
|
+
require "LOLastfm/checkers/#{name}"
|
211
|
+
rescue LoadError; end
|
181
212
|
end
|
182
213
|
|
183
214
|
block = self.class.checkers[name]
|
@@ -187,9 +218,9 @@ class LOLastfm
|
|
187
218
|
@checker.stop
|
188
219
|
end
|
189
220
|
|
190
|
-
@checker = Checker.new(self, name, args.shift, &block)
|
191
|
-
|
192
|
-
|
221
|
+
@checker = Checker.new(self, name, args.shift, &block).tap {|c|
|
222
|
+
c.start if started?
|
223
|
+
}
|
193
224
|
end
|
194
225
|
|
195
226
|
def hint (*args)
|
data/lib/LOLastfm/checker.rb
CHANGED
@@ -62,17 +62,21 @@ class Checker
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def stop (&block)
|
65
|
-
@timers.each {|timer|
|
66
|
-
clear_timeout(timer)
|
67
|
-
}
|
68
|
-
|
69
65
|
if block
|
70
66
|
@stop_block = block
|
71
67
|
else
|
68
|
+
@stopped = true
|
69
|
+
|
70
|
+
@timers.each {|timer|
|
71
|
+
clear_timeout(timer)
|
72
|
+
}
|
73
|
+
|
72
74
|
@stop_block.call if @stop_block
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
78
|
+
def stopped?; !!@stopped; end
|
79
|
+
|
76
80
|
def hint (*args, &block)
|
77
81
|
if block
|
78
82
|
@hint_block = block
|
@@ -11,7 +11,6 @@
|
|
11
11
|
require 'cmus'
|
12
12
|
|
13
13
|
class Cmus::Controller::Status
|
14
|
-
memoize
|
15
14
|
def to_song
|
16
15
|
return unless song
|
17
16
|
|
@@ -33,26 +32,37 @@ LOLastfm.define_checker :cmus do
|
|
33
32
|
settings.default[:every] = 5
|
34
33
|
settings.default[:timeout] = 0.005
|
35
34
|
|
36
|
-
@cmus = Cmus::Controller.new(settings[:socket], settings[:timeout])
|
37
|
-
|
35
|
+
if @cmus = Cmus::Controller.new(settings[:socket], settings[:timeout]) rescue false
|
36
|
+
@last = @cmus.status
|
38
37
|
|
39
|
-
|
40
|
-
|
38
|
+
if @last == :play
|
39
|
+
now_playing @last.to_song
|
40
|
+
end
|
41
41
|
end
|
42
42
|
|
43
43
|
set_interval settings[:every] do
|
44
|
+
unless @cmus
|
45
|
+
@cmus = Cmus::Controller.new(settings[:socket], settings[:timeout]) rescue next
|
46
|
+
@last = @cmus.status
|
47
|
+
end
|
48
|
+
|
49
|
+
unless status = @cmus.status rescue nil
|
50
|
+
@cmus = nil
|
51
|
+
next
|
52
|
+
end
|
53
|
+
|
44
54
|
status = @cmus.status
|
45
55
|
|
46
56
|
if status == :stop
|
47
|
-
if @last != :stop && LOLastfm::Song.is_scrobblable?(@last.song.position, @last.song.duration)
|
57
|
+
if @last != :stop && (@last.to_song.stream? || LOLastfm::Song.is_scrobblable?(@last.song.position, @last.song.duration))
|
48
58
|
listened @last.to_song
|
49
|
-
else
|
50
|
-
stopped_playing!
|
51
59
|
end
|
60
|
+
|
61
|
+
stopped_playing!
|
52
62
|
elsif status == :pause
|
53
63
|
stopped_playing!
|
54
64
|
else
|
55
|
-
if @last != :stop && (@last.to_song != status.to_song || @last.song.position > status.song.position) && LOLastfm::Song.is_scrobblable?(@last.song.position, @last.song.duration)
|
65
|
+
if @last != :stop && (@last.to_song != status.to_song || @last.song.position > status.song.position + 30) && (@last.to_song.stream? || LOLastfm::Song.is_scrobblable?(@last.song.position, @last.song.duration))
|
56
66
|
listened @last.to_song
|
57
67
|
end
|
58
68
|
|
@@ -10,23 +10,25 @@
|
|
10
10
|
|
11
11
|
require 'moc'
|
12
12
|
|
13
|
-
class Moc::Controller::Status
|
14
|
-
memoize
|
13
|
+
class Moc::Controller::Status::Live
|
15
14
|
def to_song
|
16
15
|
return unless song
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
file = song.file
|
18
|
+
tags = song.tags
|
19
|
+
|
20
|
+
if file.start_with?('http://') || file.start_with?('ftp://')
|
21
|
+
comment = file
|
20
22
|
else
|
21
|
-
path =
|
23
|
+
path = file
|
22
24
|
end
|
23
25
|
|
24
26
|
LOLastfm::Song.new(true,
|
25
|
-
track:
|
26
|
-
title:
|
27
|
-
artist:
|
28
|
-
album:
|
29
|
-
length:
|
27
|
+
track: tags.track,
|
28
|
+
title: tags.title,
|
29
|
+
artist: tags.artist,
|
30
|
+
album: tags.album,
|
31
|
+
length: tags.time,
|
30
32
|
comment: comment,
|
31
33
|
path: path,
|
32
34
|
stream: !!comment
|
@@ -38,34 +40,58 @@ LOLastfm.define_checker :moc do
|
|
38
40
|
settings.default[:socket] = '~/.moc/socket2'
|
39
41
|
settings.default[:every] = 5
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
+
create = proc {
|
44
|
+
unless moc = Moc::Controller.new(settings[:socket]) rescue false
|
45
|
+
set_timeout settings[:every], &create unless stopped?
|
46
|
+
end
|
43
47
|
|
44
|
-
|
45
|
-
|
46
|
-
end
|
48
|
+
Thread.new {
|
49
|
+
song, position = nil
|
47
50
|
|
48
|
-
|
49
|
-
|
51
|
+
begin
|
52
|
+
moc.loop {|e|
|
53
|
+
if e == :audio_stop
|
54
|
+
next unless song
|
50
55
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
56
|
+
if song.stream?
|
57
|
+
listened song
|
58
|
+
else
|
59
|
+
if LOLastfm::Song.is_scrobblable?(position, song.length)
|
60
|
+
listened song
|
61
|
+
else
|
62
|
+
stopped_playing!
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
song = nil
|
67
|
+
elsif e == :tags
|
68
|
+
elsif e == :audio_start
|
69
|
+
now_playing song = moc.status(true).to_song
|
70
|
+
elsif e == :state && moc.status(true) == :paused
|
71
|
+
stopped_playing!
|
72
|
+
elsif e == :ctime
|
73
|
+
unless song
|
74
|
+
now_playing song = moc.status(true).to_song
|
75
|
+
end
|
63
76
|
|
64
|
-
|
65
|
-
|
77
|
+
if song.stream?
|
78
|
+
if moc.status(true).song.title != song.title
|
79
|
+
listened song
|
80
|
+
now_playing song = moc.status(true).to_song
|
81
|
+
end
|
82
|
+
else
|
83
|
+
position = moc.status(true).song.position
|
84
|
+
end
|
85
|
+
end
|
86
|
+
}
|
87
|
+
rescue Exception => e
|
88
|
+
$stderr.puts e.message
|
89
|
+
$stderr.puts e.backtrace
|
66
90
|
end
|
67
|
-
end
|
68
91
|
|
69
|
-
|
70
|
-
|
92
|
+
set_timeout settings[:every], &create unless stopped?
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
create.call
|
71
97
|
end
|
@@ -9,19 +9,34 @@
|
|
9
9
|
#++
|
10
10
|
|
11
11
|
require 'glyr'
|
12
|
+
require 'tmpdir'
|
13
|
+
require 'fileutils'
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
module Glyr
|
16
|
+
class Source
|
17
|
+
def to_hash
|
18
|
+
{ name: name, quality: quality, speed: speed, language_aware: language_aware? }
|
19
|
+
end
|
16
20
|
end
|
21
|
+
|
22
|
+
class Result
|
23
|
+
def to_hash
|
24
|
+
{ source: source, url: url, data: data }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
File.join(Dir.tmpdir, rand.to_s).tap {|path|
|
29
|
+
FileUtils.mkpath(path)
|
30
|
+
cache_at path
|
31
|
+
}
|
17
32
|
end
|
18
33
|
|
19
34
|
LOLastfm.define_command :lyrics? do
|
20
35
|
song = now_playing?
|
21
36
|
|
22
37
|
EM.defer -> {
|
23
|
-
Glyr.query
|
24
|
-
}, ->
|
25
|
-
send_line
|
38
|
+
Glyr.query(title: song.title, artist: song.artist, album: song.album).lyrics
|
39
|
+
}, -> results {
|
40
|
+
send_line results.map(&:to_hash).to_json
|
26
41
|
}
|
27
42
|
end
|
data/lib/LOLastfm/connection.rb
CHANGED
@@ -16,6 +16,10 @@ define_command :use do |*args|
|
|
16
16
|
use *args
|
17
17
|
end
|
18
18
|
|
19
|
+
define_command :commands do |*args|
|
20
|
+
commands *args
|
21
|
+
end
|
22
|
+
|
19
23
|
define_command :listened do |song|
|
20
24
|
listened song
|
21
25
|
end
|
@@ -55,7 +59,7 @@ class Connection < EventMachine::Protocols::LineAndTextProtocol
|
|
55
59
|
command, arguments = JSON.parse(line)
|
56
60
|
|
57
61
|
if block = LOLastfm.commands[command.to_sym.downcase]
|
58
|
-
|
62
|
+
instance_exec *arguments, &block
|
59
63
|
end
|
60
64
|
rescue => e
|
61
65
|
$stderr.puts e.to_s
|
data/lib/LOLastfm/song.rb
CHANGED
data/lib/LOLastfm/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: LOLastfm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: lastfm
|
@@ -43,28 +43,14 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: call-me
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
54
|
-
type: :runtime
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
46
|
description:
|
63
47
|
email: meh@paranoici.org
|
64
48
|
executables:
|
65
49
|
- LOLastfm
|
66
50
|
- LOLastfm-cmus
|
67
|
-
- LOLastfm-
|
51
|
+
- LOLastfm-lyrics
|
52
|
+
- LOLastfm-now-playing
|
53
|
+
- LOLastfm-send
|
68
54
|
extensions: []
|
69
55
|
extra_rdoc_files: []
|
70
56
|
files:
|
@@ -72,7 +58,9 @@ files:
|
|
72
58
|
- README.md
|
73
59
|
- bin/LOLastfm
|
74
60
|
- bin/LOLastfm-cmus
|
75
|
-
- bin/LOLastfm-
|
61
|
+
- bin/LOLastfm-lyrics
|
62
|
+
- bin/LOLastfm-now-playing
|
63
|
+
- bin/LOLastfm-send
|
76
64
|
- lib/LOLastfm.rb
|
77
65
|
- lib/LOLastfm/cache.rb
|
78
66
|
- lib/LOLastfm/checker.rb
|