dotfiles

My personal shell configs and stuff
git clone git://git.alex.balgavy.eu/dotfiles.git
Log | Files | Refs | Submodules | README | LICENSE

discogs (2958B)


      1 #!/usr/bin/env ruby
      2 require "net/http"
      3 require "openssl"
      4 require "json"
      5 
      6 # Add easy access to hash members for JSON stuff
      7 class Hash
      8   def method_missing(meth, *_args, &_block)
      9     raise NoMethodError unless key?(meth.to_s)
     10 
     11     self[meth.to_s]
     12   end
     13 end
     14 
     15 class Discogs
     16   def initialize_http
     17     @http = Net::HTTP.new(@base_url.host, @base_url.port)
     18     @http.use_ssl = true
     19     @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
     20   end
     21 
     22   def auth
     23     my_user_token = ENV["DISCOGS_API_TOKEN"]
     24 
     25     if my_user_token.nil?
     26       raise "No user token set."
     27     end
     28 
     29     @token = my_user_token
     30   end
     31 
     32   def initialize
     33     auth
     34     @base_url = URI("https://api.discogs.com")
     35     initialize_http
     36   end
     37 
     38   def url_call_get(url)
     39     request = Net::HTTP::Get.new(url)
     40     request["Authorization"] = "Discogs token=#{@token}"
     41     begin
     42       resp = @http.request(request)
     43     rescue Exception => e
     44       puts("Connection broke (#{e}), retrying request to #{url}")
     45       binding.irb if File.exist?("/tmp/rubydebug")
     46 
     47       sleep(2)
     48       initialize_http
     49       return url_call_get(url)
     50     end
     51 
     52     if resp["X-Discogs-Ratelimit-Remaining"].to_i == 0
     53       sleep(60)
     54       return url_call_get(url)
     55     elsif resp.code_type != Net::HTTPOK
     56       puts("Request #{url} returned #{resp}")
     57       exit(1)
     58     end
     59 
     60     JSON.parse(resp.read_body)
     61   end
     62 
     63   def api_call_get(endpoint, params = {})
     64     url = @base_url + endpoint
     65     url.query = URI.encode_www_form(params)
     66     url_call_get(url)
     67   end
     68 
     69   def search(query)
     70     return api_call_get("/database/search", {q: query})
     71   end
     72 
     73 end
     74 
     75 # Join the rest of the arguments into a search string
     76 query = ARGV.join(" ")
     77 
     78 # Initialise arrays
     79 genres, styles = [], []
     80 
     81 # Search for the query
     82 discogs = Discogs::new
     83 search = discogs.search("#{query}")
     84 
     85 if search.results.empty?
     86   STDERR.puts("discogs: no search results")
     87   exit(1)
     88 end
     89 
     90 # Add the genres of the first result
     91 search["results"].each do |result|
     92   if result.include?("genre") && !result["genre"].empty?
     93     genres.push(result["genre"].first)
     94     # result.genre.each do |g|
     95     #   if g.include? ","
     96     #     g.split(",").each { |x| genres.push "#{x}" }
     97     #   else
     98     #     genres.push "#{g}"
     99     #   end
    100     # end
    101     break
    102   end
    103 end
    104 
    105 # Add the styles of the first result
    106 search["results"].each do |result|
    107   if result.include?("style") && !result["style"].empty?
    108     styles.push(result["style"].to_a.first)
    109     # result.style.to_a.each { |x| styles.push("#{x}") }
    110   end
    111 
    112   break
    113 end
    114 
    115 # Add the url of the first result
    116 # url = "http://discogs.com#{search.results[0].uri}".split(" ")
    117 
    118 # Join everything together into a 2d array
    119 # 2 different separators ("~", ",") because bash
    120 # result = [genres.join("~"), styles.join("~"), url]
    121 result = [genres.join("~"), styles.join("~")]
    122 
    123 # Unless only asking for genre, also add title
    124 if !(ARGV.include?("-g") || ARGV.include?("--genre"))
    125   result = [search.results.first.title] + result
    126 end
    127 
    128 # Send result to stdout
    129 puts(result.join("/"))