dhun 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
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