]> git.r.bdr.sh - rbdr/lyricli.rb/commitdiff
First Batch of Source Changes [Broken]
authorBen Beltran <redacted>
Fri, 5 Oct 2012 06:16:08 +0000 (01:16 -0500)
committerBen Beltran <redacted>
Fri, 5 Oct 2012 06:16:08 +0000 (01:16 -0500)
Changing the architecture of lyricli, passing from "Experiment" to
"Project". So here goes. This definitely doesn't work. So no sense
even trying. I still need to transfer a lot of things, including
docs and tests. Aaaaand. That's it.

Gemfile
Gemfile.lock
bin/lrc [new file with mode: 0644]
lib/lyricli.rb [new file with mode: 0755]
lib/lyricli/config.rb [new file with mode: 0644]
lib/lyricli/sources/arguments.rb [new file with mode: 0644]
lib/lyricli/sources/itunes.rb [new file with mode: 0644]
lib/lyricli/sources/rdio.rb [new file with mode: 0644]
lib/lyricli/util.rb [new file with mode: 0644]
lib/source_manager.rb [new file with mode: 0644]

diff --git a/Gemfile b/Gemfile
index 5b8fcbd0e24ec6bfe2448dfd9c8a1478a8905eab..4c91c06270901addbb30e8826e5b2917464a66c4 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,6 @@
 source :rubygems
 
 source :rubygems
 
-gem 'nokogiri'
-gem 'multi_json'
-gem 'rdio'
+gem 'nokogiri', "~> 1.5.5"
+gem 'multi_json', "~> 1.3.6"
+gem 'rdio', "~> 0.1.0"
+gem "launchy", "~> 2.1.2"
index 4c016b52c9e728c9421949b81331d90ca68106b6..a15cfa4f77a8efba644110478d3817928272648d 100644 (file)
@@ -1,7 +1,10 @@
 GEM
   remote: http://rubygems.org/
   specs:
 GEM
   remote: http://rubygems.org/
   specs:
+    addressable (2.3.2)
     json (1.7.5)
     json (1.7.5)
+    launchy (2.1.2)
+      addressable (~> 2.3)
     multi_json (1.3.6)
     nokogiri (1.5.5)
     oauth (0.4.7)
     multi_json (1.3.6)
     nokogiri (1.5.5)
     oauth (0.4.7)
@@ -13,6 +16,7 @@ PLATFORMS
   ruby
 
 DEPENDENCIES
   ruby
 
 DEPENDENCIES
-  multi_json
-  nokogiri
-  rdio
+  launchy (~> 2.1.2)
+  multi_json (~> 1.3.6)
+  nokogiri (~> 1.5.5)
+  rdio (~> 0.1.0)
diff --git a/bin/lrc b/bin/lrc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/lyricli.rb b/lib/lyricli.rb
new file mode 100755 (executable)
index 0000000..928adad
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/env ruby -w
+
+require 'uri'
+require 'net/http'
+require 'multi_json'
+require 'nokogiri'
+require 'open-uri'
+require 'launchy'
+
+# This shit causes a lot of warnings. Quick Hack.
+original_verbosity = $VERBOSE
+$VERBOSE = nil
+require 'rdio'
+$VERBOSE = original_verbosity
+
+class Lyricli
+
+  # TODO: Change the whole fucking thing
+  def initialize
+    @rdio_key = "sddac5t8akqrzh5b6kg53jfm"
+    @rdio_secret = "PRcB8TggFr"
+    @token_path = File.expand_path("~/.rdio_token")
+
+    #Expand the symlink and get the path
+    if File.symlink?(__FILE__) then
+      path = File.dirname(File.readlink(__FILE__))
+    else
+      path = File.dirname(__FILE__)
+    end
+
+    # Get the current rdio track
+    @rdio = init_rdio
+    rdio_track
+
+    #Get the current iTunes track
+    current = `osascript #{path}/current_song.scpt`
+    if current and not current.empty? then
+      current = current.split("<-SEP->")
+      @artist ||= current[0]
+      @song ||= current[1]
+    end
+  end
+
+  def init_rdio
+
+    if File.exists?(@token_path)
+      f = File.new(@token_path, "r")
+      begin
+        token = MultiJson.decode(f.read)
+      rescue
+        token = create_rdio_token
+      end
+    else
+      token = create_rdio_token
+    end
+
+    Rdio::SimpleRdio.new([@rdio_key, @rdio_secret], token)
+  end
+
+
+  def exit_with_error
+    abort "Usage: #{$0} artist song"
+  end
+
+  def get_lyrics
+
+    #Use the API to search
+    uri = URI("http://lyrics.wikia.com/api.php?artist=#{self.sanitize_param @artist}&song=#{self.sanitize_param @song}&fmt=realjson")
+    begin
+      res = Net::HTTP.get(uri)
+      res = MultiJson.decode(res)
+
+      #Get the actual lyrics url
+      doc = Nokogiri::HTML(open(res['url']))
+      node = doc.search(".lyricbox").first
+    rescue
+      abort "Lyrics not found :("
+    end
+
+    #Remove the rtMatcher nodes
+    node.search(".rtMatcher").each do |n|
+      n.remove
+    end
+
+    #Maintain new lines
+    node.search("br").each do |br|
+      br.replace "\n"
+    end
+
+    #Retrieve the lyrics
+    puts node.inner_text
+  end
+
+  def check_params
+    self.exit_with_error if @artist.nil? or @artist.empty?
+    self.exit_with_error if @song.nil? or @song.empty?
+  end
+
+  def sanitize_param(p)
+    URI.encode_www_form_component(p.gsub(/ /, "+")).gsub("%2B", "+")
+  end
+end
+
+
+lrc = Lyricli.new
+lrc.check_params
+lrc.get_lyrics
diff --git a/lib/lyricli/config.rb b/lib/lyricli/config.rb
new file mode 100644 (file)
index 0000000..da999ec
--- /dev/null
@@ -0,0 +1,47 @@
+module Lyricli
+  class Config
+
+    def initialize
+      @config_path = "~/.lyricli.conf"
+      @config = load_config
+    end
+
+    @@instance = Config.new
+
+    def self.instance
+      @@instance
+    end
+
+    def [](key)
+      @config[key]
+    end
+
+    def []=(key, value)
+      @config[key] = value
+      save_config
+    end
+
+    private_class_method :new
+
+    private
+
+    # TODO: Apart from this, load a default yml that will be used for this.
+    # And just extend everything from the user's config.
+    def load_config
+      path = File.expand_path(@config_path)
+      if File.exists?(path)
+        file = File.new(path, "r")
+        MultiJson.decode(file.read)
+      else
+        {}
+      end
+    end
+
+    def save_config
+      path = File.expand_path(@config_path)
+      file = File.new(path, "w")
+      file.print(MultiJson.encode(@config))
+      file.close
+    end
+  end
+end
diff --git a/lib/lyricli/sources/arguments.rb b/lib/lyricli/sources/arguments.rb
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/lyricli/sources/itunes.rb b/lib/lyricli/sources/itunes.rb
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/lyricli/sources/rdio.rb b/lib/lyricli/sources/rdio.rb
new file mode 100644 (file)
index 0000000..afb736d
--- /dev/null
@@ -0,0 +1,65 @@
+module Lyricli
+  module Sources
+    module Rdio
+
+      # Returns the name of the source, in snake_case
+      def self.name
+        "rdio"
+      end
+
+      # The enable method should run all of the tasks needed to validate
+      # the source. In the case of Rdio it has to authenticate with OAuth.
+      def self.enable
+        # Validation Code
+        @config = Lyricli::Config
+        unless @config[:rdio_auth_token] && !@config[:rdio_auth_token].empty?
+          create_auth_token
+        end
+
+      end
+
+      # Instantiates everything it needs to run.
+      def self.start
+        @rdio = Rdio::SimpleRdio.new([@config[:rdio_key], @config[:rdio_secret]], @config[:rdio_auth_token])
+      end
+
+      # The current_track method should return the name of the current
+      # artist and song.
+      # @return [Hash] A hash containing the current `:song` and `:artist`.
+      def self.current_track
+        u = @rdio.call('currentUser', {'extras' => 'lastSongPlayed'})
+        artist = u["result"]["lastSongPlayed"]["artist"]
+        song = u["result"]["lastSongPlayed"]["name"]
+        {artist: artist, song: song}
+      end
+
+      # The reset method resets any configurations it may have
+      def self.reset
+        # Reset Code
+      end
+
+      private
+
+      # Signs in to rdio with our credentials and requests access for a new auth
+      # token.
+      def create_auth_token
+        rdio = Rdio::SimpleRdio.new([@config])
+
+        # Request Authorization
+        puts "Follow this URL to authorize lyricli:"
+        auth_url = rdio.begin_authentication('oob')
+        puts auth_url
+        Launchy.open(auth_url)
+
+        # Request Code, Obtain Token
+        print "Please type the authorization code: "
+        auth_code = gets.chomp
+        token = rdio.complete_authentication(auth_code)
+
+        @config[:rdio_auth_token] = token
+        token
+      end
+
+    end
+  end
+end
diff --git a/lib/lyricli/util.rb b/lib/lyricli/util.rb
new file mode 100644 (file)
index 0000000..9ae9f6c
--- /dev/null
@@ -0,0 +1,14 @@
+module Lyricli
+  module Util
+    def camelize(str)
+      str.split('_').map {|w| w.capitalize}.join
+    end
+
+    def parse_class(class_name)
+      klass = Module.const_get(class_name)
+      return klass if klass.is_a?(Class)
+      rescue NameError
+          return nil
+    end
+  end
+end
diff --git a/lib/source_manager.rb b/lib/source_manager.rb
new file mode 100644 (file)
index 0000000..834326d
--- /dev/null
@@ -0,0 +1,47 @@
+module Lyricli
+  class SourceManager
+
+    include Lyricli::Util
+
+    def initialize
+      @enabled_sources = []
+      @config = Lyricli::Config
+    end
+
+    def enable(source_name)
+      if source_module = module_exists?(camelize(str))
+        source_module.enable
+        @config[:enabled_sources] << klass.name
+      else
+        raise Lyricli::EnableSourceException
+      end
+    end
+
+    def disable(source_name)
+      if source_module = module_exists?(camelize(str))
+        @config[:enabled_sources].delete(klass.name)
+      else
+        raise Lyricli::DisableSourceException
+      end
+    end
+
+    def reset(source_name)
+      if source_module = module_exists?(camelize(str))
+        source_module.reset
+        disable(source_name)
+      else
+        raise Lyricli::ResetSourceException
+      end
+    end
+
+    def start
+      @config[:enabled_sources].each do |source|
+        begin
+          source.start
+        rescue
+          fail "Source #{source.name} has failed to start. Please reset the source by running `#{$0} source reset #{source.name}.`"
+        end
+      end
+    end
+  end
+end