Permalink
Browse files

rebranding, add followers support and some bugfixes

  • Loading branch information...
1 parent b59e610 commit a8c36c4d04e347f4a4ffb9ec260bcf3192592b84 nov committed Mar 4, 2009
View
@@ -0,0 +1,16 @@
+module Smartfm
+end
+
+require 'date'
+require 'net/https'
+require 'uri'
+
+require 'rubygems'
+require 'json'
+
+require 'ext/hash'
+require 'smartfm/core'
+require 'smartfm/rest_client'
+require 'smartfm/model'
+
+Smartfm::Config.init
View
@@ -0,0 +1,3 @@
+require 'smartfm/core/version'
+require 'smartfm/core/config'
+require 'smartfm/core/auth'
View
@@ -0,0 +1,39 @@
+require 'oauth/consumer'
+
+class Smartfm::Auth
+ attr_accessor :mode, :auth_token
+
+ class Basic
+ attr_reader :username, :password
+
+ def initialize(username, password)
+ @username = username
+ @password = password
+ end
+ end
+
+ def initialize(options = {})
+ if options[:username] && options[:password]
+ @mode = :basic_auth
+ @auth_token = Basic.new(options[:username], options[:password])
+ elsif options[:token] && options[:secret]
+ @mode = :oauth
+ @auth_token = OAuth::AccessToken.new(Smartfm::Auth.consumer, options[:token], options[:secret])
+ else
+ raise ArgumentError.new('{:auth => "oauth_access_token", :secret => "oauth_access_token_secret"} or {:username "smartfm_username", :password => "smartfm_password"} is needed')
+ end
+ end
+
+ def self.consumer
+ @@consumer ||= OAuth::Consumer.new(
+ Smartfm::Config.oauth_consumer_key,
+ Smartfm::Config.oauth_consumer_secret,
+ :http_method => Smartfm::Config.oauth_http_method,
+ :scheme => Smartfm::Config.oauth_scheme,
+ :site => Smartfm::Config.api_base_url,
+ :authorize_url => "#{Smartfm::Config.base_url}/oauth/authorize"
+ )
+ end
+
+ alias_method :account, :auth_token
+end
View
@@ -0,0 +1,51 @@
+require 'singleton'
+
+class Smartfm::Config
+ include Singleton
+ ATTRIBUTES = [ :protocol, :host, :port, :api_protocol, :api_host, :api_port, :api_key, :timeout,
+ :oauth_consumer_key, :oauth_consumer_secret, :oauth_http_method, :oauth_scheme,
+ :user_agent, :application_name, :application_version, :application_url ]
+ attr_accessor *ATTRIBUTES
+
+ def self.init(&block)
+ conf = Smartfm::Config.instance
+ { :protocol => 'http',
+ :host => 'smart.fm',
+ :port => 80,
+ :api_protocol => 'http',
+ :api_host => 'api.smart.fm',
+ :api_port => 80,
+ :api_key => '',
+ :timeout => 30,
+ :oauth_consumer_key => '',
+ :oauth_consumer_secret => '',
+ :oauth_http_method => :post,
+ :oauth_scheme => :header,
+ :user_agent => 'default',
+ :application_name => 'smart.fm gem',
+ :application_version => Smartfm::Version.to_version,
+ :application_url => 'http://github.com/nov/smartfm'
+ }.each do |key, value| conf.send("#{key}=", value) end
+ yield conf if block_given?
+ conf
+ end
+
+ def base_url
+ port = self.port==80 ? nil : ":#{self.port}"
+ "#{self.protocol}://#{self.host}#{port}"
+ end
+
+ def api_base_url
+ port = self.api_port==80 ? nil : ":#{self.api_port}"
+ "#{self.api_protocol}://#{self.api_host}#{port}"
+ end
+
+ # hack: Object.timeout is already defined..
+ def self.timeout
+ instance.timeout
+ end
+
+ def self.method_missing(method, *args)
+ Smartfm::Config.instance.send(method, *args)
+ end
+end
@@ -0,0 +1,14 @@
+module Smartfm::Version
+ MAJOR = 0
+ MINOR = 3
+ REVISION = 0
+ class << self
+ def to_version
+ "#{MAJOR}.#{MINOR}.#{REVISION}"
+ end
+
+ def to_name
+ "#{MAJOR}_#{MINOR}_#{REVISION}"
+ end
+ end
+end
View
@@ -0,0 +1,5 @@
+require 'smartfm/model/base'
+require 'smartfm/model/user'
+require 'smartfm/model/list'
+require 'smartfm/model/item'
+require 'smartfm/model/sentence'
View
@@ -0,0 +1,26 @@
+class Smartfm::Base
+
+ def self.attributes; self::ATTRIBUTES end
+
+ def attributes; self.class.attributes end
+
+ def self.deserialize(hash, params = {})
+ return nil if hash.nil?
+
+ klass = params[:as] ? params[:as] : self
+ if hash.is_a?(Array)
+ hash.inject([]) { |results, hash|
+ hash.symbolize_keys!
+ results << klass.new(hash)
+ }
+ else
+ hash.symbolize_keys!
+ klass.new(hash)
+ end
+ end
+
+ def deserialize(hash, params = {})
+ self.class.deserialize(hash, params)
+ end
+
+end
View
@@ -0,0 +1,174 @@
+class Smartfm::Item < Smartfm::Base
+ ATTRIBUTES = [:sentences, :responses, :cue, :id, :list]
+ READONLY_ATTRIBUTES = [:sentences, :responses, :cue, :id]
+ attr_accessor *(ATTRIBUTES - READONLY_ATTRIBUTES)
+ attr_reader *READONLY_ATTRIBUTES
+
+ class Response < Smartfm::Base
+ ATTRIBUTES = [:text, :text_with_character, :type, :language]
+ READONLY_ATTRIBUTES = [:type]
+ attr_accessor *(ATTRIBUTES - READONLY_ATTRIBUTES)
+ attr_reader *READONLY_ATTRIBUTES
+
+ def initialize(params = {})
+ @text = params[:text]
+ @type = params[:type]
+ @language = params[:language]
+ end
+ end
+
+ class Cue < Smartfm::Base
+ ATTRIBUTES = [:type, :text, :image, :sound, :part_of_speech, :language, :transliterations]
+ READONLY_ATTRIBUTES = [:sound]
+ attr_accessor *(ATTRIBUTES - READONLY_ATTRIBUTES)
+ attr_reader *READONLY_ATTRIBUTES
+
+ def initialize(params = {})
+ @type = params[:type]
+ @text = params[:text]
+ @image = params[:image]
+ @sound = params[:sound]
+ @part_of_speech = params[:part_of_speech]
+ @language = params[:language]
+ @transliterations = params[:transliterations]
+ end
+ end
+
+ def self.recent(params = {})
+ hash = Smartfm::RestClient::Item.recent(params)
+ self.deserialize(hash) || []
+ end
+
+ def self.find(item_id, params = {})
+ params[:id] = item_id
+ hash = Smartfm::RestClient::Item.find(params)
+ self.deserialize(hash)
+ end
+
+ def self.matching(keyword, params = {})
+ params[:keyword] = keyword
+ hash = Smartfm::RestClient::Item.matching(params)
+ self.deserialize(hash) || []
+ end
+
+ def self.extract(text, params = {})
+ params[:text] = text
+ hash = Smartfm::RestClient::Item.extract(params)
+ self.deserialize(hash) || []
+ end
+
+ def self.create(auth, params = {})
+ self.new(params).save(auth)
+ end
+
+ def initialize(params = {})
+ params[:responses] = [params[:response]] if params[:response]
+ @id = params[:id].to_i
+ @list = params[:list]
+ @cue = self.deserialize(params[:cue], :as => Smartfm::Item::Cue)
+ @responses = self.deserialize(params[:responses], :as => Smartfm::Item::Response)
+ @sentences = self.deserialize(params[:sentences], :as => Smartfm::Sentence)
+ end
+
+ def save(auth)
+ begin
+ item_id = Smartfm::RestClient::Item.create(auth, self.to_post_data)
+ rescue
+ return false
+ end
+ Smartfm::Item.find(item_id)
+ end
+
+ def add_image(auth, params)
+ post_params = if params.is_a?(String)
+ { 'image[url]' => params }
+ else
+ image_params = {
+ 'image[url]' => params[:url],
+ 'image[list_id]' => params[:list_id]
+ }
+ if params[:attribution]
+ attribution_params = {
+ 'attribution[media_entity]' => params[:attribution][:media_entity],
+ 'attribution[author]' => params[:attribution][:media_entity],
+ 'attribution[author_url]' => params[:attribution][:media_entity],
+ 'attribution[attribution_license_id]' => params[:attribution][:media_entity]
+ }
+ image_params.merge(attribution_params)
+ else
+ image_params
+ end
+ end
+ Smartfm::RestClient::Item.add_image(auth, post_params.merge(:id => self.id))
+ end
+
+ def add_sound(auth, params)
+ post_params = if params.is_a?(String)
+ { 'sound[url]' => params }
+ else
+ sound_params = {
+ 'sound[url]' => params[:url],
+ 'sound[list_id]' => params[:list_id]
+ }
+ if params[:attribution]
+ attribution_params = {
+ 'attribution[media_entity]' => params[:attribution][:media_entity],
+ 'attribution[author]' => params[:attribution][:media_entity],
+ 'attribution[author_url]' => params[:attribution][:media_entity],
+ 'attribution[attribution_license_id]' => params[:attribution][:media_entity]
+ }
+ sound_params.merge(attribution_params)
+ else
+ sound_params
+ end
+ end
+ Smartfm::RestClient::Item.add_sound(auth, post_params.merge(:id => self.id))
+ end
+
+ def add_tags(auth, *tags)
+ post_params = {}
+ tags.each_with_index do |tag, idx|
+ if tag.is_a?(String)
+ post_params["semantic_tags[#{idx}][name]"] = tag
+ else
+ post_params["semantic_tags[#{idx}][name]"] = tag[:name]
+ post_params["semantic_tags[#{idx}][disambiguation]"] = tag[:disambiguation]
+ end
+ end
+ Smartfm::RestClient::Item.add_tags(auth, post_params.merge(:id => self.id))
+ end
+
+ protected
+
+ def to_post_data
+ self.validate
+ post_data = {
+ 'cue[text]' => self.cue.text,
+ 'cue[language]' => self.cue.language,
+ 'cue[part_of_speech]' => self.cue.part_of_speech,
+ 'response[text]' => self.response.text,
+ 'response[language]' => self.response.language
+ }
+ # Optional attributes
+ if self.list
+ post_data['item[list_id]'] = self.list.id
+ end
+ if response.text_with_character
+ post_data['character_response[text]'] = self.response.character_text
+ end
+ post_data
+ end
+
+ def validate
+ raise ArgumentError.new("Item cue[text] is required.") if self.cue.text.nil? or self.cue.text.empty?
+ raise ArgumentError.new("Item cue[language] is required.") if self.cue.language.nil? or self.cue.language.empty?
+ raise ArgumentError.new("Item cue[part_of_speech] is required.") if self.cue.part_of_speech.nil? or self.cue.part_of_speech.empty?
+ raise ArgumentError.new("Item response[text] is required.") if self.response.text.nil? or self.response.text.empty?
+ raise ArgumentError.new("Item response[language] is required.") if self.response.language.nil? or self.response.language.empty?
+ end
+
+ def response
+ self.responses.first
+ end
+
+end
Oops, something went wrong.

0 comments on commit a8c36c4

Please sign in to comment.