Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Dynamically build objects and define missing classes while parsing re…

…sources.
  • Loading branch information...
commit b6320c73fcd29181317f7e414d07a7fefb7ae124 1 parent dbdfacc
Riccardo Cambiassi authored
5 README.markdown
View
@@ -45,6 +45,11 @@ SocialCast gem is a ruby interface to the SocialCast REST API
This is just the first draft of the wrapper. It can be improved in many, many ways.
The API is not completely covered either: some of interesing stuff, like message and comments attachments have been left out.
+One current limitation is that the parser will refuse to consider
+elements that contain a dot, so I'm excluding those deliberately for the
+time being (see
+lib/socialcastr/sax/active_resource.rb#start_element).
+
Feel free to help (see Contributing below)
## TODO
15 lib/socialcastr.rb
View
@@ -73,5 +73,20 @@ def self.api
raise MissingConfiguration unless config.username
API.new(config.username, config.password, config.domain, config.format, config.debug)
end
+
+ def self.element_class(method)
+ class_name = method.to_s.gsub(/^[a-z]|-[a-z]/i) { |a| a.sub("-", '').upcase }
+ unless Socialcastr.const_defined?(class_name)
+ Socialcastr.const_set(class_name, Class.new(Socialcastr::Base))
+ end
+ return class_name
+ end
+ def self.collection_class(method)
+ class_name = method.to_s.gsub(/^[a-z]|-[a-z]/i) { |a| a.sub("-", '').upcase }
+ unless Socialcastr.const_defined?(class_name)
+ Socialcastr.const_set(class_name, Class.new(Socialcastr::Collection))
+ end
+ return class_name
+ end
end
22 lib/socialcastr/base.rb
View
@@ -1,3 +1,4 @@
+require 'nokogiri'
require 'socialcastr/sax/active_resource'
module Socialcastr
class Base
@@ -67,9 +68,25 @@ def param_name(variable_name)
"#{self.class.model_name.downcase}[#{variable_name.to_s.gsub /@/,''}]"
end
+ def method_missing(method, *args, &block)
+ if !@doc[method.to_s].nil?
+ value = @doc[method.to_s]
+ case value.class
+ when Array
+ element = Socialcastr.const_get(Socialcastr.collection_class(method)).new
+ element.instance_variable_set("@doc", value)
+ return element
+ else
+ return value
+ end
+ end
+ end
+
+
+
class << self
def parse(xml="")
- source= ActiveResourceXML.new
+ source= SAX::ActiveResource.new
parser = Nokogiri::XML::SAX::Parser.new(source)
parser.parse(xml)
from_hash(source.doc)
@@ -77,7 +94,8 @@ def parse(xml="")
def from_hash(h)
base = new()
- base.doc = h
+ base.instance_variable_set("@doc", h)
+ return base
end
def api
21 lib/socialcastr/collection.rb
View
@@ -3,28 +3,11 @@ class Collection < Base
include Enumerable
def each &block
- members.each{|member| block.call(member)}
+ @doc.each{|member| block.call(member)}
end
def size
- members.size
- end
-
- def members
- send self.class.members_method
- end
-
- def self.collection_of(name, options={})
- if options[:as]
- @members_method = options[:as]
- else
- @members_method = name
- end
- elements name, options
- end
-
- def self.members_method
- @members_method
+ @doc.size
end
end
end
31 lib/socialcastr/sax/active_resource.rb
View
@@ -8,6 +8,18 @@ def initialize
@doc = nil
end
+ def error(s)
+ puts "ERROR: #{s}"
+ end
+
+ def warning(s)
+ puts "WARN: #{s}"
+ end
+
+ def cdata_block(s)
+ characters(s)
+ end
+
def parse_attrs(attrs=[])
type = "hash"
attrs.each do |attr|
@@ -22,6 +34,10 @@ def parse_attrs(attrs=[])
end
def start_element name, attrs = []
+ if name =~ /\./
+ @nil = true
+ return nil
+ end
type = parse_attrs(attrs)
unless @nil
@types.push type
@@ -37,7 +53,7 @@ def start_element name, attrs = []
end
def characters(s)
- return if s =~ /^[\s\n\t]*$/
+ return if (s =~ /^[\s\n\t]*$/ || @nil)
@types[-1] = "string"
@values[-1] = s
end
@@ -48,19 +64,24 @@ def end_element name
else
value = @values.pop
type = @types.pop
+ if type == "hash"
+ element = Socialcastr.const_get(Socialcastr.element_class(name)).new
+ element.instance_variable_set("@doc", value)
+ else
+ element = value
+ end
if @values[-1]
if @types[-1] == "array"
- @values[-1].push value
+ @values[-1].push element
else
- @values[-1][name] = value
+ @values[-1][name] = element
end
else
- @doc = { name => value }
+ @doc = { name => element }
end
end
end
-
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.