Class: Henchman::DropboxAssistant
- Inherits:
-
Object
- Object
- Henchman::DropboxAssistant
- Defined in:
- lib/dbx_assistant.rb
Instance Method Summary collapse
- #download(selection, dropbox_path) ⇒ Object
- #get_results(track, artist) ⇒ Object
-
#initialize(config, debug) ⇒ DropboxAssistant
constructor
A new instance of DropboxAssistant.
- #search(value, filter = nil, dir = @config[:dropbox]) ⇒ Object
- #search_for(selection) ⇒ Object
Constructor Details
#initialize(config, debug) ⇒ DropboxAssistant
Returns a new instance of DropboxAssistant.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/dbx_assistant.rb', line 9 def initialize config, debug begin @search_limit = 500 @debug = debug @config = config @client = Dropbox::Client.new @config[:dropbox][:access_token] # stop words from http://nlp.stanford.edu/IR-book/html/htmledition/dropping-common-terms-stop-words-1.html @stop_words = ['a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'for', 'from', 'has', 'he', 'in', 'is', 'it', 'its', 'of', 'on', 'that', 'the', 'to', 'was', 'were', 'will', 'with'] true rescue DropboxError => msg puts "#{DateTime.now.strftime('%m-%d-%Y %H:%M:%S')}|"\ "Couldn't connect to Dropbox (#{msg}). "\ "Run `henchman stop` then `henchman configure` "\ "to configure Dropbox connection." false end end |
Instance Method Details
#download(selection, dropbox_path) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/dbx_assistant.rb', line 30 def download selection, dropbox_path puts "#{DateTime.now.strftime('%m-%d-%Y %H:%M:%S')}|"\ "Downloading #{selection.reject{|k,v| k == :path || k == :id}.values.join(':')} from #{dropbox_path}" begin # download the file content, body = @client.download dropbox_path # make sure we have the directory to put it in trgt_dir = File.join @config[:root], selection[:artist], selection[:album] puts trgt_dir if @debug system 'mkdir', '-p', trgt_dir # save the file file_save_path = File.join trgt_dir, File.basename(dropbox_path) puts file_save_path if @debug open(file_save_path, 'w') {|f| f.puts body } file_save_path rescue DropboxError => msg puts "#{DateTime.now.strftime('%m-%d-%Y %H:%M:%S')}|"\ "Error downloading Dropbox file #{dropbox_path}: #{msg}" false rescue StandardError => msg puts "#{DateTime.now.strftime('%m-%d-%Y %H:%M:%S')}|"\ "Error saving Dropbox file #{dropbox_path} to #{trgt_dir}: #{msg}" false end end |
#get_results(track, artist) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/dbx_assistant.rb', line 76 def get_results track, artist puts "`get_results` for #{track} by #{artist}" if @debug # Search Dropbox for the file # We're only not filtering to get files because we want to check if we get 1000 results # (i.e. a maxed out playload) back. This is because the filtering happens in OUR client, # not in the Dropbox search. We're doing a simple search on only track name because we # want to minimize the number of network calls, and USUALLY this is good enough results = search track # If we get 1000 results back, it means we probably have a REALLY simple song title # and we're not assured to have the target song in our payload, since we maxed it # out. So, we'll do another search call on the artist if results.length == @search_limit puts "Maximum (#{@search_limit}) results returned" if @debug results.clear album_dirs = search artist, :dir album_dirs.each do |album| tmp_rslts = search track, :file, album['path'] results.push(*tmp_rslts) end else # Otherwise, filter off all the directories and things without the right extensions puts "Filtering out directories and incorrect file extensions" if @debug results.reject! { |result| !result.is_a? Dropbox::FileMetadata || !(@config[:file_extensions].include?(File.extname(result.path_lower)[1..-1])) } end puts "Returning #{results.length} results from `get_results`" if @debug return results end |
#search(value, filter = nil, dir = @config[:dropbox]) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/dbx_assistant.rb', line 58 def search value, filter = nil, dir = @config[:dropbox][:root] puts "Searching for #{value} in #{dir}, filtering by <#{filter}>" if @debug begin results = @client.search dir, value, 0, @search_limit puts "#{results.length} total results found" if @debug if filter == :dir results.reject! { |result| !result.is_a? Dropbox::FolderMetadata } elsif filter == :file results.reject! { |result| !result.is_a? Dropbox::FileMetadata || !(@config[:file_extensions].include?(File.extname(result.path_lower)[1..-1])) } end puts "Returning #{results.length} results for `search` (after filtering)" if @debug return results rescue DropboxError => msg raise "Error accessing Dropbox Search API|#{value}|#{dir}|#{msg}" end end |
#search_for(selection) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/dbx_assistant.rb', line 105 def search_for selection puts "#{DateTime.now.strftime('%m-%d-%Y %H:%M:%S')}|"\ "Searching for #{selection.reject{|k,v| k == :path || k == :id}.values.join(':')}" results = get_results selection[:track], selection[:artist] # if we still don't have any results, try dropping any brackets and paranthesis if results.empty? && (selection[:track].match(%r( *\[.*\] *)) || selection[:track].match(%r( *\(.*\) *))) puts "No results. Trying without brackets or parenthesis" if @debug track = selection[:track].gsub(%r( *\[.*\] *), " ").gsub(%r( *\(.*\) *), " ") results = get_results track, selection[:artist] end # if there were no results, raise err if results.empty? raise "Track not found in Dropbox: #{selection.reject{|k,v| k == :id}.values.join(':')}" else scores = Hash.new 0 tokens = Array.new track_tokens = Array.new [:artist, :album].each do |identifier| tokens |= selection[identifier].downcase .gsub(%r( +), " ") .gsub(%r(-+), "-") .strip .split(/[\s-]/) .delete_if{ |t| @stop_words.include? t } end @config[:file_extensions].each do |extension| track_tokens |= selection[:track].downcase .gsub(%r( +), " ") .gsub(%r(-+), "-") .strip .split(/[\s-]/) .map { |t| "#{t}.#{extension}" } end if @debug puts ":artist and :album tokens: #{tokens.inspect}" puts ":track tokens: #{track_tokens.inspect}" end results.each do |result| dir = "#{File.dirname(result.path_lower)}/" basename = " #{File.basename(result.path_lower)}" tokens.each do |token| if dir =~ %r(.*[\s\/-]#{token}[\s\/-].*) puts "Token #{token} found in #{dir}" if @debug if results.length == 1 return result.path_display else scores[result.path_display] += 1 end end end track_tokens.each do |token| if basename =~ %r([.]*[\s-]+#{token}) puts "Token #{token} found in #{basename}" if @debug scores[result.path_display] += 1 end end end # if the we only had one track and we're here, that means the path didn't contain # any of the album or artist tokens, so we'll say we couldn't find it if results.length == 1 raise "Track not found in Dropbox: #{selection.reject{|k,v| k == :id}.values.join(':')}" end # return the path that has the highest score scores = scores.sort_by { |path, score| score } if @debug scores.each { |score| puts score.join ': ' } end scores[-1][0] end end |