gem 'multi_json', "~> 1.3.6"
gem 'rdio', "~> 0.1.0"
gem "launchy", "~> 2.1.2"
+
+gem 'ruby-debug19', "~> 0.11.6"
remote: http://rubygems.org/
specs:
addressable (2.3.2)
+ archive-tar-minitar (0.5.2)
+ columnize (0.3.6)
json (1.7.5)
launchy (2.1.2)
addressable (~> 2.3)
+ linecache19 (0.5.12)
+ ruby_core_source (>= 0.1.4)
multi_json (1.3.6)
nokogiri (1.5.5)
oauth (0.4.7)
rdio (0.1.0)
json
oauth (>= 0.3.0)
+ ruby-debug-base19 (0.11.25)
+ columnize (>= 0.3.1)
+ linecache19 (>= 0.5.11)
+ ruby_core_source (>= 0.1.4)
+ ruby-debug19 (0.11.6)
+ columnize (>= 0.3.1)
+ linecache19 (>= 0.5.11)
+ ruby-debug-base19 (>= 0.11.19)
+ ruby_core_source (0.1.5)
+ archive-tar-minitar (>= 0.5.2)
PLATFORMS
ruby
multi_json (~> 1.3.6)
nokogiri (~> 1.5.5)
rdio (~> 0.1.0)
+ ruby-debug19 (~> 0.11.6)
require 'rdio'
$VERBOSE = original_verbosity
-class Lyricli
+# Add current path to include path
+$:.unshift File.expand_path(File.dirname(__FILE__))
+
+# Local Dependencies
+require "lyricli/util"
+require "lyricli/configuration"
+require "lyricli/lyrics_engine"
+require "lyricli/source_manager"
+require "lyricli/sources/arguments"
+require "lyricli/sources/rdio"
+require "lyricli/sources/itunes"
+
+module Lyricli
+ def self.execute
+ @lyricli = Lyricli.new
+ @lyricli.get_lyrics
+ end
- # TODO: Change the whole fucking thing
- def initialize
- @rdio_key = "sddac5t8akqrzh5b6kg53jfm"
- @rdio_secret = "PRcB8TggFr"
- @token_path = File.expand_path("~/.rdio_token")
+ class Lyricli
- #Expand the symlink and get the path
- if File.symlink?(__FILE__) then
- path = File.dirname(File.readlink(__FILE__))
- else
- path = File.dirname(__FILE__)
+ def initialize
+ @source_manager = SourceManager.new
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]
+ def exit_with_error
+ abort "Usage: #{$0} artist song"
end
- end
- def init_rdio
+ def get_lyrics
+ set_current_track
+ check_params
+
+ engine = LyricsEngine.new(@current_track[:artist], @current_track[:song])
- if File.exists?(@token_path)
- f = File.new(@token_path, "r")
begin
- token = MultiJson.decode(f.read)
- rescue
- token = create_rdio_token
+ engine.get_lyrics
+ rescue LyricsNotFoundException
+ "Lyrics not found :("
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
+ def set_current_track
+ @current_track = @source_manager.current_track
end
- #Maintain new lines
- node.search("br").each do |br|
- br.replace "\n"
+ def check_params
+ self.exit_with_error if @current_track[:artist].nil? or @current_track[:artist].empty?
+ self.exit_with_error if @current_track[:song].nil? or @current_track[:song].empty?
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
+++ /dev/null
-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
+module Lyricli
+ module Sources
+ class Arguments
+
+ class << self
+ attr_accessor :name
+ end
+
+ @name = "arguments"
+
+ # 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
+ # Nothing to do.
+ end
+
+ # Instantiates everything it needs to run.
+ def initialize
+ # Nothing to do.
+ 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 current_track
+ artist = ARGV[0]
+ song = ARGV[1]
+ {artist: artist, song: song}
+ end
+
+ # The reset method resets any configurations it may have
+ def self.reset
+ # Reset Code
+ end
+ end
+ end
+end
module Lyricli
module Sources
- module Rdio
+ class Rdio
- # Returns the name of the source, in snake_case
- def self.name
- "rdio"
+ class << self
+ attr_accessor :name
end
+ @name = "rdio"
+
# 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?
+ @config = Lyricli::Configuration.instance
+ 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])
+ def initialize
+ @name = 'rdio'
+ @config = Lyricli::Configuration.instance
+ @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"]
+ def current_track
+ response = @rdio.call('currentUser', {'extras' => 'lastSongPlayed'})
+ artist = response["result"]["lastSongPlayed"]["artist"]
+ song = response["result"]["lastSongPlayed"]["name"]
{artist: artist, song: song}
end
# 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])
+ def self.create_auth_token
+ @rdio = Rdio::SimpleRdio.new([@config["rdio_key"], @config["rdio_secret"]], @config["rdio_auth_token"])
# Request Authorization
puts "Follow this URL to authorize lyricli:"
auth_code = gets.chomp
token = rdio.complete_authentication(auth_code)
- @config[:rdio_auth_token] = token
+ @config["rdio_auth_token"] = token
token
end
end
def parse_class(class_name)
- klass = Module.const_get(class_name)
- return klass if klass.is_a?(Class)
+ begin
+ path = "Sources::#{class_name}"
+ return eval(path)
rescue NameError
- return nil
+ return nil
+ end
+ end
+
+ def sanitize_param(p)
+ URI.encode_www_form_component(p.gsub(/ /, "+")).gsub("%2B", "+")
end
end
end
+++ /dev/null
-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