listlace 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b99b9e103972f209f74a53b2328cc01aef9ee89f
4
- data.tar.gz: 335147f7cbda256c7ed70273b14736edf46d697e
3
+ metadata.gz: 5e2d5c543763b463ddeb7d210dd9462eaca05944
4
+ data.tar.gz: a91502ded9981eade141ba10f7ee90b4fdf0e9ee
5
5
  SHA512:
6
- metadata.gz: 1e7de49eb1117788b45e41fccee8bbbb987f3b1ee6d1bff7415096a510b4853bf8f2cd7c383d542f2b88cfb7ed5db8f33d92a116cb2203589a3a58a6b2395231
7
- data.tar.gz: bd62fdc1d420b838d3699ea10f773e9cd98ceece1ef443a4f4bba7f44cace6d18e35ab91ef442049d15251e713d43edd23922c0098305c0829b28fe3447bdd91
6
+ metadata.gz: da90361e229cf18c7f273ea58fa1bae79f2ae6e7f8b3fbfbf9d7e7163798c3653299562602863030a36937c0b98fd9a57b785ce119e707992a9a34fd0057142b
7
+ data.tar.gz: 116b0aa40716b9cde245cb3042fcf0efd37b89a119f17fcbe36ad8697de08c30fa7f72966d73e1378d78e5d9f60337c3f7fbdd0519c42a438e11de7d77189823
data/Gemfile.lock CHANGED
@@ -1,22 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- listlace (0.0.1)
4
+ listlace (0.1.0)
5
5
  bundler
6
- mpd_client
7
6
  pry
7
+ ruby-mpd
8
8
 
9
9
  GEM
10
10
  remote: http://rubygems.org/
11
11
  specs:
12
12
  coderay (1.1.0)
13
13
  method_source (0.8.2)
14
- mpd_client (0.0.3)
15
14
  pry (0.9.12.6)
16
15
  coderay (~> 1.0)
17
16
  method_source (~> 0.8)
18
17
  slop (~> 3.4)
19
18
  rake (0.9.2.2)
19
+ ruby-mpd (0.3.1)
20
20
  slop (3.5.0)
21
21
 
22
22
  PLATFORMS
data/README.md CHANGED
@@ -19,13 +19,149 @@ The gem gives you an executable, so do this:
19
19
 
20
20
  It gives you a prompt, which is just a Ruby prompt, with the commands below implemented as methods.
21
21
 
22
+ ## Selectors
23
+
24
+ Query your music library and build playlists using selectors. There are selectors for each tag (artist, album, title, etc.) As an example, here is how `artist` works:
25
+
26
+ ♫> artist "thirsty cups"
27
+ => [8 songs]
28
+
29
+ It returned an Array of 8 Songs. To do an exact, case-sensitive search, use `artist_exact`:
30
+
31
+ ♫> artist_exact "thirsty cups"
32
+ => []
33
+ ♫> artist_exact "The Thirsty Cups"
34
+ => [8 songs]
35
+
36
+ The first one didn't match anything, the second one matched the same 8 songs.
37
+
38
+ You can also pass in a `Regexp` or a `Symbol`:
39
+
40
+ ♫> artist :the_thirsty_cups
41
+ => [8 songs]
42
+ ♫> artist /the thirst(y|ier|iest) cups/
43
+ => [8 songs]
44
+
45
+ Underscores in symbols are interpreted as spaces.
46
+
47
+ Here's a list of all tag selectors: `title`, `title_exact`, `artist`, `artist_exact`, `album`, `album_exact`, `genre`, and `genre_exact`.
48
+
49
+ In addition to tag selectors, here are some special selectors:
50
+
51
+ ### all
52
+
53
+ `all` returns all the songs in your library.
54
+
55
+ ♫> all
56
+ => [3560 songs]
57
+
58
+ ### none
59
+
60
+ `none` returns an empty playlist.
61
+
62
+ ♫> none
63
+ => []
64
+
65
+ ### search
66
+
67
+ `search` will match **any** tag that contains your query.
68
+
69
+ ♫> search "thirsty"
70
+ => [8 songs]
71
+
72
+ ### where, where\_exact
73
+
74
+ `where` and `where_exact` let you specify multiple queries for different tags:
75
+
76
+ ♫> where(artist: "thirsty", title: "belljar")
77
+ => [1 song]
78
+
22
79
  ## Commands
23
80
 
24
81
  ### p
25
82
 
26
- `p` is like a play/pause button. If the player is paused, it unpauses. If the player is playing, then it pauses. If the player is stopped, then it starts playing.
83
+ `p` is like a play/pause button. If the player is paused, it unpauses. If the player is playing, then it pauses. If the player is stopped, then it starts playing. If you pass it a playlist, it will set the queue to that playlist and begin playing it.
84
+
85
+ ♫> p
86
+ ♫> p album :in_the_faxed_atmosphere
87
+
88
+ ### q
89
+
90
+ `q` without any arguments returns the queue (the current playlist). If you call `q` with a playlist as an argument, it will replace the queue with that playlist.
91
+
92
+
93
+ ♫> q genre :trance
94
+ ♫> q
95
+ => [53 songs]
96
+
97
+ ### stop
98
+
99
+ `stop` stops playback.
100
+
101
+ ♫> stop
102
+
103
+ ### list
104
+
105
+ `list` with no arguments lists all the songs in your music library. If you pass it a playlist, it will list all the songs in that playlist.
106
+
107
+ ♫> list
108
+ Air - 10 000 Hz Legend - Electronic Performers
109
+ Air - 10 000 Hz Legend - How Does It Make You Feel?
110
+ Air - 10 000 Hz Legend - Radio #1
111
+ ...
112
+ ♫> list title :fish
113
+ Eisley - Currents - Blue Fish
114
+ Moonboots - Elfin Princess - The Fish Said Hello
115
+ Radiohead - In Rainbows - Weird Fishes/Arpeggi
116
+ Thee More Shallows - A History of Sport Fishing - A History of Sport Fishing
117
+
118
+ ### artists
119
+
120
+ `artists` with no arguments lists all the artists in your music library. If you pass it a playlist, it will list all the artists in that playlist.
121
+
122
+ ♫> artists
123
+ Air (55 songs)
124
+ Amplifier (53 songs)
125
+ Andrew Bird (93 songs)
126
+ ...
127
+ ♫> artists genre(:trance)
128
+ Infected Mushroom (13 songs)
129
+ Gouryella (3 songs)
130
+ Safri Duo feat. Clark Anderson (6 songs)
131
+ Safri Duo (16 songs)
132
+
133
+ ### albums
134
+
135
+ `albums` with no arguments lists all the albums in your music library. If you pass it a playlist, it will list all the albums in that playlist.
136
+
137
+ ♫> albums
138
+ Air - 10 000 Hz Legend (11 songs)
139
+ Air - Love 2 (12 songs)
140
+ Air - Moon Safari (10 songs)
141
+ ...
142
+ ♫> albums artist(:infected_mushroom)
143
+ Infected Mushroom - Converting Vegetarians (22 songs)
144
+ Infected Mushroom - IM the Supervisor (9 songs)
145
+ Infected Mushroom - Legend of the Black Shawarma (11 songs)
146
+ Infected Mushroom - Stretched (4 songs)
147
+ Infected Mushroom - Vicious Delicious (11 songs)
148
+
149
+ ### genres
150
+
151
+ `genres` with no arguments lists all the genres in your music library. If you pass it a playlist, it will list all the genres in that playlist.
152
+
153
+ ♫> genres
154
+ Trance (53 songs)
155
+ Hip-Hop (14 songs)
156
+ Jazz (10 songs)
157
+ ...
158
+ ♫> genres title(:constantinople)
159
+ TMBG (1 song)
27
160
 
28
161
  ### mpd
29
162
 
30
163
  `mpd` gives you an instance of the `MPDClient` object, which you can use to send any `mpd` command that isn't available in Listlace yet. This'll probably be removed once I actually implement all the commands.
31
164
 
165
+ ♫> mpd.version
166
+ => "0.16.0"
167
+
@@ -1,17 +1,71 @@
1
1
  class Listlace
2
2
  module Commands
3
- REPEAT_SYMBOL = "\u221E"
4
- TIMES_SYMBOL = "\u00D7"
5
-
6
- def p
7
- case mpd.status["state"]
8
- when "play"
9
- mpd.pause(1)
10
- when "pause"
11
- mpd.pause(0)
12
- when "stop"
3
+ def p(*playlist)
4
+ if playlist.empty?
5
+ case mpd.status[:state]
6
+ when :play
7
+ mpd.pause = true
8
+ when :pause
9
+ mpd.pause = false
10
+ when :stop
11
+ mpd.play
12
+ end
13
+ else
14
+ mpd.clear
15
+ playlist.flatten.each do |song|
16
+ mpd.add song.file
17
+ end
13
18
  mpd.play
14
19
  end
20
+ nil
21
+ end
22
+
23
+ def stop
24
+ mpd.stop
25
+ nil
26
+ end
27
+
28
+ def q(*playlist)
29
+ if playlist.empty?
30
+ mpd.queue
31
+ else
32
+ mpd.clear
33
+ playlist.flatten.each do |song|
34
+ mpd.add song.file
35
+ end
36
+ nil
37
+ end
38
+ end
39
+
40
+ def list(playlist = nil)
41
+ (playlist || all).each do |song|
42
+ puts "#{song.artist} - #{song.album} - #{song.title}"
43
+ end
44
+ nil
45
+ end
46
+
47
+ def artists(playlist = nil)
48
+ (playlist || all).group_by(&:artist).each do |artist, songs|
49
+ plural = (songs.length == 1) ? "" : "s"
50
+ puts "#{artist} (#{songs.length} song#{plural})"
51
+ end
52
+ nil
53
+ end
54
+
55
+ def albums(playlist = nil)
56
+ (playlist || all).group_by(&:album).each do |album, songs|
57
+ plural = (songs.length == 1) ? "" : "s"
58
+ puts "#{songs.first.artist} - #{album} (#{songs.length} song#{plural})"
59
+ end
60
+ nil
61
+ end
62
+
63
+ def genres(playlist = nil)
64
+ (playlist || all).group_by(&:genre).each do |genre, songs|
65
+ plural = (songs.length == 1) ? "" : "s"
66
+ puts "#{genre} (#{songs.length} song#{plural})"
67
+ end
68
+ nil
15
69
  end
16
70
  end
17
71
  end
@@ -0,0 +1,25 @@
1
+ class Array
2
+ def playlist?
3
+ @is_playlist ||= all? { |x| x.is_a? MPD::Song }
4
+ end
5
+
6
+ alias _original_inspect inspect
7
+ def inspect
8
+ if playlist?
9
+ plural = (length == 1) ? "" : "s"
10
+ "[#{length} song#{plural}]"
11
+ else
12
+ _original_inspect
13
+ end
14
+ end
15
+
16
+ alias _original_pretty_inspect pretty_inspect
17
+ def pretty_inspect
18
+ if playlist?
19
+ inspect
20
+ else
21
+ _original_pretty_inspect
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,44 @@
1
+ class Listlace
2
+ module Selectors
3
+ TAG_SELECTORS = %w(title artist album genre)
4
+
5
+ TAG_SELECTORS.each do |tag|
6
+ define_method(tag) do |what|
7
+ case what
8
+ when Regexp
9
+ what = Regexp.new(what.source, Regexp::IGNORECASE) # case-insensitize
10
+ all.select { |song| song.send(tag).to_s =~ what }
11
+ when Symbol
12
+ mpd.where(tag => what.to_s.tr("_", " "))
13
+ when String
14
+ mpd.where(tag => what)
15
+ end
16
+ end
17
+
18
+ define_method("#{tag}_exact") do |what|
19
+ mpd.where({tag => what}, {strict: true})
20
+ end
21
+ end
22
+
23
+ def all
24
+ mpd.songs
25
+ end
26
+
27
+ def none
28
+ []
29
+ end
30
+
31
+ def search(what)
32
+ mpd.where any: what
33
+ end
34
+
35
+ def where(params)
36
+ mpd.where(params)
37
+ end
38
+
39
+ def where_exact(params)
40
+ mpd.where(params, {strict: true})
41
+ end
42
+ end
43
+ end
44
+
data/lib/listlace.rb CHANGED
@@ -1,15 +1,19 @@
1
- require "mpd_client"
1
+ require "ruby-mpd"
2
+
3
+ require "listlace/core_ext/array"
2
4
 
3
5
  require "listlace/commands"
6
+ require "listlace/selectors"
4
7
 
5
8
  class Listlace
6
9
  attr_reader :mpd
7
10
 
8
11
  include Commands
12
+ include Selectors
9
13
 
10
14
  def initialize(host, port)
11
- @mpd = MPDClient.new
12
- @mpd.connect(host, port)
15
+ @mpd = MPD.new(host, port)
16
+ @mpd.connect
13
17
  end
14
18
 
15
19
  def disconnect
data/listlace.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "listlace"
3
- s.version = "0.1.0"
4
- s.date = "2014-03-15"
3
+ s.version = "0.2.0"
4
+ s.date = "2014-03-22"
5
5
  s.summary = "An mpd (music player daemon) client with a Ruby shell as the interface."
6
6
  s.description = "Listlace is an mpd (music player daemon) client with a Ruby shell as the interface."
7
7
  s.author = "Jeremy Ruten"
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.files += ["bin/listlace"]
16
16
  s.files += Dir["lib/**/*.rb"]
17
17
 
18
- %w(bundler pry mpd_client).each do |gem_name|
18
+ %w(bundler pry ruby-mpd).each do |gem_name|
19
19
  s.add_runtime_dependency gem_name
20
20
  end
21
21
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: listlace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Ruten
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-15 00:00:00.000000000 Z
11
+ date: 2014-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: mpd_client
42
+ name: ruby-mpd
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -81,6 +81,8 @@ files:
81
81
  - bin/listlace
82
82
  - lib/listlace.rb
83
83
  - lib/listlace/commands.rb
84
+ - lib/listlace/core_ext/array.rb
85
+ - lib/listlace/selectors.rb
84
86
  - listlace.gemspec
85
87
  homepage: http://github.com/yjerem/listlace
86
88
  licenses: