dhun 0.5.4 → 0.5.5

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/FIX.md CHANGED
@@ -1,5 +1,4 @@
1
1
  ## Fixes/Improvements required
2
2
 
3
- * Better Argument Handling. For e.g. `dhun play` w/o any arguments still works
4
-
5
- * Maintaining history of all files played in the session
3
+ * Refactor multiple calls to result.to_json
4
+ * Refactor handler calls by converting it from module to subclass of EventMachine::Connection object
data/README.md CHANGED
@@ -29,42 +29,53 @@ the `gem` command to compile the native extensions.
29
29
  Pass the `-d` option to run the server as a daemon in the background. See
30
30
  `dhun -h` for more options.
31
31
 
32
- ### Playing Files
32
+
33
+ ### Querying for files
33
34
 
34
35
  Dhun uses Spotlight to query for music files. Just specify a keyword, and Dhun
35
36
  will look for files matching that keyword and start playing them.
36
37
 
37
- You can also query the Spotlight database before playing the files.
38
+ You can also query the Spotlight database before playing the files, with the
39
+ `query` command.
38
40
 
39
41
  $ dhun query here
40
- 9 Results
42
+ 3 Results
41
43
  /Users/deepak/Music/iTunes/iTunes Media/Music/Edward Sharpe & The Magnetic Zeros/Here Comes/01 40 Day Dream.mp3
42
44
  /Users/deepak/Music/iTunes/iTunes Media/Music/Edward Sharpe & The Magnetic Zeros/Here Comes/02 Janglin.mp3
43
45
  /Users/deepak/Music/iTunes/iTunes Media/Music/Edward Sharpe & The Magnetic Zeros/Here Comes/03 Carries On.mp3
44
- /Users/deepak/Music/Amazon MP3/Edward Sharpe & The Magnetic Zeros/Here Comes/01 - 40 Day Dream.mp3
45
- /Users/deepak/Music/Amazon MP3/Edward Sharpe & The Magnetic Zeros/Here Comes/02 - Janglin.mp3
46
- /Users/deepak/Music/Amazon MP3/Edward Sharpe & The Magnetic Zeros/Here Comes/03 - Carries On.mp3
47
- /Users/deepak/Dropbox/shared/music/Here Comes/02 - Janglin.mp3
48
- /Users/deepak/Dropbox/shared/music/Here Comes/01 - 40 Day Dream.mp3
49
- /Users/deepak/Dropbox/shared/music/Here Comes/03 - Carries On.mp3
50
46
 
51
- And then, when you are ready to play the files. Note that the `play` command
52
- will remove anything that may be already there on your queue. To add files,
53
- use `enqueue`.
47
+ You can use query filters like `album:sid` or `artist:rahman`. Currently
48
+ `album`, `artist`, `title`, `genre` and `file` filters are supported.
49
+
50
+ $ dhun query genre:world album:gypsy
51
+ 5 results
52
+ /Users/deepak/Dropbox/shared/music/gypsy/Putumayo - Gypsy Groove - 11 - Eastenders - Vino Iubirea Mea (!DelaDap Remix) (Germany).mp3
53
+ /Users/deepak/Dropbox/shared/music/gypsy/Putumayo - Gypsy Groove - 10 - Luminescent Orchestrii - Amari Szi, Amari (Amon Remix) (USA).mp3
54
+ /Users/deepak/Dropbox/shared/music/gypsy/Putumayo - Gypsy Groove - 09 - Kistehén Tánczenekar - Virágok a Réten (Romano Drom Remix) (Hungary).mp3
55
+ /Users/deepak/Dropbox/shared/music/gypsy/Putumayo - Gypsy Groove - 08 - Anselmo Crew - Süt Ictim Dilim Yandi (Hungary).mp3
56
+ /Users/deepak/Dropbox/shared/music/gypsy/Putumayo - Gypsy Groove - 07 - Magnifico & Turbolentza - Zh Ne Sui Pa Pur Tua (Slovenia).mp3
57
+
58
+ You can even mix the filters with a regular query like.
59
+
60
+ $ dhun query genre:world album:gypsy Czech
61
+ 2 Results
62
+ /Users/deepak/Dropbox/shared/music/gypsy/Putumayo - Gypsy Groove - 01 - !DelaDap - Zsa Manca (Czech Republic-Hungary).mp3
63
+ /Users/deepak/Dropbox/shared/music/gypsy/Putumayo - Gypsy Groove - 03 - Gipsy.cz - Jednou (Czech Republic).mp3
64
+
65
+ Note that if you want to pass filters longer than a word, you will need to
66
+ enclose the argument in double quotes, like `dhun query "artist:akli d"`
67
+
68
+ ### Playing Files
69
+
70
+ When you are ready to play the files, pass the query to the `play` command.
71
+ Note that the `play` command will remove anything that may be already there on
72
+ your queue. To append files to queue, use `enqueue`.
54
73
 
55
74
  $ dhun play here
56
- 9 files queued for playing
75
+ 3 files queued for playing
57
76
  /Users/deepak/Music/iTunes/iTunes Media/Music/Edward Sharpe & The Magnetic Zeros/Here Comes/01 40 Day Dream.mp3
58
77
  /Users/deepak/Music/iTunes/iTunes Media/Music/Edward Sharpe & The Magnetic Zeros/Here Comes/02 Janglin.mp3
59
78
  /Users/deepak/Music/iTunes/iTunes Media/Music/Edward Sharpe & The Magnetic Zeros/Here Comes/03 Carries On.mp3
60
- /Users/deepak/Music/Amazon MP3/Edward Sharpe & The Magnetic Zeros/Here Comes/01 - 40 Day Dream.mp3
61
- /Users/deepak/Music/Amazon MP3/Edward Sharpe & The Magnetic Zeros/Here Comes/02 - Janglin.mp3
62
- /Users/deepak/Music/Amazon MP3/Edward Sharpe & The Magnetic Zeros/Here Comes/03 - Carries On.mp3
63
- /Users/deepak/Dropbox/shared/music/Here Comes/02 - Janglin.mp3
64
- /Users/deepak/Dropbox/shared/music/Here Comes/01 - 40 Day Dream.mp3
65
- /Users/deepak/Dropbox/shared/music/Here Comes/03 - Carries On.mp3
66
-
67
- More advanced querying support is coming soon.
68
79
 
69
80
  ### Controlling Playback
70
81
 
@@ -97,8 +108,7 @@ Status
97
108
  /Users/deepak/Dropbox/shared/music/Here Comes/01 - 40 Day Dream.mp3
98
109
  /Users/deepak/Dropbox/shared/music/Here Comes/03 - Carries On.mp3
99
110
 
100
- Enqueuing more files. Note that `dhun play` will empty the current queue
101
- before adding new files.
111
+ Enqueuing more files.
102
112
 
103
113
  $ dhun enqueue chup
104
114
  1 files queued for playing.
@@ -116,7 +126,6 @@ These features are planned in the next few releases
116
126
 
117
127
  * Playing previous song, using something like `dhun prev`
118
128
  * Skipping ahead by more than one file, like `dhun next 2` or `dhun prev 2`
119
- * Advanced querying support with filters, like `dhun play "artist:Rahman"`
120
129
 
121
130
  And someday..
122
131
 
data/dhun.gemspec CHANGED
@@ -1,8 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dhun'
3
- s.version = '0.5.4'
3
+ s.version = '0.5.5'
4
4
  s.summary = "Minimalist music player for OS X"
5
- s.date = '2009-12-10'
5
+ s.date = '2009-12-14'
6
6
  s.email = 'deepak.jois@gmail.com'
7
7
  s.homepage = 'http://github.com/deepakjois/dhun'
8
8
  s.has_rdoc = false
data/lib/dhun.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Dhun
2
- VERSION = '0.5.4'
2
+ VERSION = '0.5.5'
3
3
 
4
4
  autoload :Runner, 'dhun/runner'
5
5
  autoload :Controller, 'dhun/controller'
@@ -23,7 +23,8 @@ module Dhun
23
23
  end
24
24
 
25
25
  def query(*args)
26
- q = Query.new(args.join(' '))
26
+ abort_if_empty_args(args)
27
+ q = Query.new(args)
27
28
  if q.is_valid?
28
29
  files = q.execute_spotlight_query
29
30
  puts(files.empty? ? "No Results Found" : "#{files.size} Results\n" + files.join("\n"))
@@ -33,6 +34,7 @@ module Dhun
33
34
  end
34
35
 
35
36
  def play(*args)
37
+ abort_if_empty_args(args)
36
38
  resp = get_json_response("play", args)
37
39
  return unless resp
38
40
  # Process response
@@ -47,6 +49,7 @@ module Dhun
47
49
  end
48
50
 
49
51
  def enqueue(*args)
52
+ abort_if_empty_args(args)
50
53
  resp = get_json_response("enqueue",args)
51
54
  return unless resp
52
55
  # Process response
@@ -76,6 +79,13 @@ module Dhun
76
79
  end
77
80
  end
78
81
 
82
+ def history
83
+ resp = get_json_response("history")
84
+ return unless resp
85
+ puts resp[:message]
86
+ print_list(resp[:history]) unless resp[:history].empty?
87
+ end
88
+
79
89
  def next(*args)
80
90
  resp = get_json_response("next")
81
91
  puts resp[:message] if resp
@@ -112,7 +122,7 @@ module Dhun
112
122
  resp = client.send(cmd)
113
123
  end
114
124
 
115
- def get_json_response(command,*args)
125
+ def get_json_response(command,args=[])
116
126
  begin
117
127
  resp = send_command(command,args)
118
128
  return Result.from_json_str(resp)
@@ -123,6 +133,10 @@ module Dhun
123
133
  end
124
134
  end
125
135
 
136
+ def abort_if_empty_args(args)
137
+ abort "You must pass in atleast one argument" if args.empty?
138
+ end
139
+
126
140
  def print_list(list)
127
141
  list.each { |item| puts item }
128
142
  end
data/lib/dhun/handler.rb CHANGED
@@ -5,13 +5,13 @@ module Dhun
5
5
  def stop
6
6
  result = Result.new :success, "Dhun is stopping"
7
7
  Server.stop
8
- Player.instance.pause
8
+ Player.instance.stop
9
9
  return result.to_json
10
10
  end
11
11
 
12
12
  def play(*args)
13
13
  @player = Player.instance
14
- q = Query.new(args.join(" "))
14
+ q = Query.new(args)
15
15
  if q.is_valid?
16
16
  files = q.execute_spotlight_query
17
17
  if files.empty?
@@ -57,6 +57,13 @@ module Dhun
57
57
  result = Result.new :success, status_msg, :now_playing => now_playing, :queue => queue
58
58
  result.to_json
59
59
  end
60
+
61
+ def history
62
+ @player = Player.instance
63
+ status_msg = @player.history.empty? ? "No files in history" : "#{@player.history.size} files in history"
64
+ result = Result.new :success, status_msg, :history => @player.history
65
+ result.to_json
66
+ end
60
67
 
61
68
  def next(*args)
62
69
  @player = Player.instance
data/lib/dhun/player.rb CHANGED
@@ -5,6 +5,7 @@ module Dhun
5
5
  include Singleton
6
6
 
7
7
  attr_reader :queue
8
+ attr_reader :history
8
9
  attr_reader :status
9
10
  attr_reader :current
10
11
 
@@ -12,6 +13,7 @@ module Dhun
12
13
 
13
14
  def initialize
14
15
  @queue = []
16
+ @history = []
15
17
  @logger = Logger.instance
16
18
  @status = :stopped
17
19
  end
@@ -46,6 +48,7 @@ module Dhun
46
48
  @current = @queue.shift
47
49
  logger.log "Playing #{@current}"
48
50
  DhunExt.play_file @current
51
+ @history.unshift @current
49
52
  end
50
53
  @status = :stopped
51
54
  logger.log "Finished playing #{@current}"
@@ -69,13 +72,14 @@ module Dhun
69
72
 
70
73
  def stop
71
74
  @status = :stopped
72
- @current = nil
73
75
  DhunExt.stop
74
76
  # Wait for @player_thread to exit cleanly
75
77
  @player_thread.join unless @player_thread.nil?
78
+ logger.debug "Stopped"
76
79
  end
77
80
 
78
81
  def next
82
+ logger.debug "Switching to next"
79
83
  stop # stops current track
80
84
  next_track = @queue.first
81
85
  play # start playing with the next track
data/lib/dhun/query.rb CHANGED
@@ -1,23 +1,49 @@
1
1
  require 'dhun_ext'
2
+
2
3
  module Dhun
3
4
  class Query
4
5
 
5
6
  MD_ITEMS = [:kMDItemAlbum, :kMDItemAuthors, :kMDItemComposer, :kMDItemDisplayName, :kMDItemFSName, :kMDItemTitle, :kMDItemMusicalGenre]
6
- attr_reader :query_string
7
+ MAPPINGS = { "file" => :kMDItemFSName, "album" => :kMDItemAlbum, "artist" => :kMDItemAuthors, "title" => :kMDItemTitle, "genre" => :kMDItemMusicalGenre }
8
+
7
9
  attr_reader :spotlight_query
8
10
 
9
- def initialize(query_string)
10
- @query_string = query_string
11
+ def initialize(args)
12
+ @query_args = args
11
13
  parse
12
14
  end
13
15
 
14
16
  def parse
15
- str = MD_ITEMS.collect do |item|
16
- "#{item.to_s} == '#{@query_string}'wc"
17
- end.join(" || ")
17
+ return if @query_args.empty?
18
+ filters = []
19
+ strings = []
20
+
21
+ @query_args.each do |arg|
22
+ # Check if it is a filter
23
+ if filter?(arg)
24
+ filters.push(arg)
25
+ else
26
+ strings.push(arg)
27
+ end
28
+ end
29
+
30
+ mappings = MD_ITEMS.clone
31
+ fq = filters.collect do |f|
32
+ fltr,query = *(f.split(":"))
33
+ md_item = MAPPINGS[fltr]
34
+ mappings.delete md_item
35
+ "#{md_item} == '#{query.strip}'wc"
36
+ end.join(" && ")
37
+
18
38
 
19
- @spotlight_query = "kMDItemContentTypeTree == 'public.audio' && (#{str})"
20
- #puts @spotlight_query
39
+ template = "%s == '%s'wc"
40
+ sq = strings.collect do |keyword|
41
+ q = mappings.collect { |key| template % [key,keyword] }.join(" || ")
42
+ "( #{q} )"
43
+ end.join(" && ")
44
+
45
+ @spotlight_query = ["kMDItemContentTypeTree == 'public.audio'", fq, sq].select { |s| s.length > 0 }.join(" && ")
46
+ Logger.instance.debug @spotlight_query
21
47
  @is_valid = true
22
48
  end
23
49
 
@@ -25,20 +51,16 @@ module Dhun
25
51
  @is_valid
26
52
  end
27
53
 
54
+ def filter?(str)
55
+ return false unless str.index ":"
56
+ a,b = *(str.split(":"))
57
+ # Check if filter is valid
58
+ return MAPPINGS.keys.member?(a)
59
+ end
60
+
28
61
  # Use extension to query spotlight
29
62
  def execute_spotlight_query
30
63
  return DhunExt.query_spotlight(@spotlight_query)
31
64
  end
32
-
33
- def get_metadata_item(field)
34
- case field
35
- when "album" then :kMDItemAlbum
36
- when "artist" then :kMDItemAuthors
37
- when "composer" then :kMDItemComposer
38
- when "title" then :kMDItemTitle
39
- when "genre" then :kMDItemMusicalGenre
40
- else "Unknown"
41
- end
42
- end
43
65
  end
44
66
  end
data/lib/dhun/runner.rb CHANGED
@@ -5,7 +5,7 @@ module Dhun
5
5
  # Heavily lifted from Thin codebase
6
6
  class Runner
7
7
  COMMANDS = %w(start query)
8
- CLIENT_COMMANDS = %w(stop play pause resume next enqueue status shuffle)
8
+ CLIENT_COMMANDS = %w(stop play pause resume next enqueue status shuffle history)
9
9
  # Parsed options
10
10
  attr_accessor :options
11
11
 
@@ -94,7 +94,11 @@ EOF
94
94
 
95
95
  def run_command
96
96
  controller = Controller.new(@options)
97
- controller.send(@command,*@arguments)
97
+ begin
98
+ controller.send(@command,*@arguments)
99
+ rescue ArgumentError
100
+ abort "Illegal arguments passed to #{@command}"
101
+ end
98
102
  end
99
103
  end
100
104
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dhun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deepak Jois
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-10 00:00:00 -08:00
12
+ date: 2009-12-14 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency