c3s 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Manifest CHANGED
@@ -13,21 +13,4 @@ lib/pubsub/node.rb
13
13
  lib/pubsub/nodetracker.rb
14
14
  lib/pubsub/publisher.rb
15
15
  lib/pubsub/subscriber.rb
16
- pkg/c3s-0.3.2.gem
17
- pkg/c3s-0.3.2.tar.gz
18
- pkg/c3s-0.3.2/Manifest
19
- pkg/c3s-0.3.2/README.rdoc
20
- pkg/c3s-0.3.2/Rakefile
21
- pkg/c3s-0.3.2/c3s
22
- pkg/c3s-0.3.2/c3s.gemspec
23
- pkg/c3s-0.3.2/lib/c3s.rb
24
- pkg/c3s-0.3.2/lib/c3s_logger.rb
25
- pkg/c3s-0.3.2/lib/component.rb
26
- pkg/c3s-0.3.2/lib/component_connection.rb
27
- pkg/c3s-0.3.2/lib/configreader.rb
28
- pkg/c3s-0.3.2/lib/databaseadapter.rb
29
- pkg/c3s-0.3.2/lib/model.rb
30
- pkg/c3s-0.3.2/lib/pubsub/node.rb
31
- pkg/c3s-0.3.2/lib/pubsub/nodetracker.rb
32
- pkg/c3s-0.3.2/lib/pubsub/publisher.rb
33
- pkg/c3s-0.3.2/lib/pubsub/subscriber.rb
16
+ lib/republisher.rb
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('c3s', '0.3.2') do |p|
5
+ Echoe.new('c3s', '0.3.3') do |p|
6
6
  p.description = "C3s library gem."
7
7
  p.url = "http://github.com/rikas/c3s"
8
8
  p.author = "Ricardo Otero"
data/c3s.gemspec CHANGED
@@ -2,20 +2,20 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{c3s}
5
- s.version = "0.3.2"
5
+ s.version = "0.3.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ricardo Otero"]
9
- s.date = %q{2010-02-11}
9
+ s.date = %q{2010-03-03}
10
10
  s.description = %q{C3s library gem.}
11
11
  s.email = %q{oterosantos@gmail.com}
12
- s.extra_rdoc_files = ["README.rdoc", "lib/c3s.rb", "lib/c3s_logger.rb", "lib/component.rb", "lib/component_connection.rb", "lib/configreader.rb", "lib/databaseadapter.rb", "lib/model.rb", "lib/pubsub/node.rb", "lib/pubsub/nodetracker.rb", "lib/pubsub/publisher.rb", "lib/pubsub/subscriber.rb"]
13
- s.files = ["Manifest", "README.rdoc", "Rakefile", "c3s", "lib/c3s.rb", "lib/c3s_logger.rb", "lib/component.rb", "lib/component_connection.rb", "lib/configreader.rb", "lib/databaseadapter.rb", "lib/model.rb", "lib/pubsub/node.rb", "lib/pubsub/nodetracker.rb", "lib/pubsub/publisher.rb", "lib/pubsub/subscriber.rb", "c3s.gemspec"]
12
+ s.extra_rdoc_files = ["README.rdoc", "lib/c3s.rb", "lib/c3s_logger.rb", "lib/component.rb", "lib/component_connection.rb", "lib/configreader.rb", "lib/databaseadapter.rb", "lib/model.rb", "lib/pubsub/node.rb", "lib/pubsub/nodetracker.rb", "lib/pubsub/publisher.rb", "lib/pubsub/subscriber.rb", "lib/republisher.rb"]
13
+ s.files = ["Manifest", "README.rdoc", "Rakefile", "c3s", "lib/c3s.rb", "lib/c3s_logger.rb", "lib/component.rb", "lib/component_connection.rb", "lib/configreader.rb", "lib/databaseadapter.rb", "lib/model.rb", "lib/pubsub/node.rb", "lib/pubsub/nodetracker.rb", "lib/pubsub/publisher.rb", "lib/pubsub/subscriber.rb", "lib/republisher.rb", "c3s.gemspec"]
14
14
  s.homepage = %q{http://github.com/rikas/c3s}
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "C3s", "--main", "README.rdoc"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{c3s}
18
- s.rubygems_version = %q{1.3.5}
18
+ s.rubygems_version = %q{1.3.6}
19
19
  s.summary = %q{C3s library gem.}
20
20
 
21
21
  if s.respond_to? :specification_version then
data/lib/c3s.rb CHANGED
@@ -18,8 +18,16 @@ require 'configreader'
18
18
  require 'databaseadapter'
19
19
  require 'c3s_logger'
20
20
 
21
+ begin
22
+ require 'xmpp4r'
23
+ rescue Exception => e
24
+ puts "Fatal Error: #{e}"
25
+ puts "Please install xmpp4r gem with 'sudo gem install xmpp4r'"
26
+ exit
27
+ end
28
+
21
29
  module C3s
22
- VERSION = "0.2.9"
30
+ VERSION = "0.3.3"
23
31
 
24
32
  def self.included(base)
25
33
  base.extend ClassMethods
data/lib/component.rb CHANGED
@@ -1,15 +1,7 @@
1
1
  require 'thread'
2
- begin
3
- require 'xmpp4r'
4
- rescue Exception => e
5
- puts "Fatal Error: #{e}"
6
- puts "Please install xmpp4r gem with 'sudo gem install xmpp4r'"
7
- exit
8
- end
9
2
  require 'xmpp4r/discovery'
10
3
  require 'xmpp4r/pubsub/helper/nodebrowser'
11
4
  require 'pubsub/publisher'
12
- require 'pubsub/subscriber'
13
5
  require 'pubsub/node'
14
6
 
15
7
  module C3s
@@ -55,7 +47,7 @@ module C3s
55
47
  # to use.
56
48
  def start
57
49
  super
58
-
50
+
59
51
  Thread.abort_on_exception = true
60
52
 
61
53
  add_iq_callback do |iq|
@@ -130,18 +122,23 @@ module C3s
130
122
  end
131
123
 
132
124
  changed = true
133
- @object = self.model.find_by_jid(data[:jid]) || self.model.new
125
+ object = self.model.find_by_jid(data[:jid]) || self.model.new
134
126
 
135
127
  $LOG.info "Saving #{config['name']} context for #{data[:jid]} #{data.inspect}"
136
- @object.update_attributes(data)
137
- changed = @object.changed?
138
- @object.save!
139
-
140
- publish(iq, stanza, changed) if @object.errors.count == 0
128
+ object.update_attributes(data)
129
+ changed = object.changed?
130
+ object.save!
131
+
132
+ if object.errors.count == 0
133
+ $LOG.info "Publishing data to node #{config['name']}:#{iq.from.to_s}"
134
+ c3snode = C3s::Node.new("#{config['name']}:#{iq.from.to_s}")
135
+ publish(c3snode, stanza, changed)
136
+ send_ok(iq)
137
+ end
141
138
 
142
139
  rescue Exception => e
143
140
  $LOG.error("#{e.inspect} #{e.backtrace.join("\n")}")
144
- send_error(iq, ['bad-request', @object.errors.full_messages.first])
141
+ send_error(iq, ['bad-request', object.errors.full_messages.first])
145
142
  end
146
143
 
147
144
  ##
@@ -181,33 +178,17 @@ module C3s
181
178
 
182
179
  ##
183
180
  # Publishes information to pubsub server
184
- # iq:: the setter iq
185
- # data:: what to publish
186
- # changed:: the data is different from last set operation?
187
- def publish(iq, data, changed)
188
- jid = (iq.is_a?(Jabber::Iq)) ? iq.from.to_s : iq
181
+ # c3snode:: [C3s::Node] the pubsub node
182
+ # data:: [String] what to publish
183
+ # changed:: [Boolean] the data is different from last set operation?
184
+ def publish(c3snode, data, changed)
189
185
  if changed
190
186
  pub = Publisher.new(self, config['pubsub'])
191
- pub.create_nodes("#{config['name']}:#{jid}")
192
- pub.publish(jid, data)
187
+ pub.create_tree(c3snode)
188
+ pub.publish(c3snode, data)
193
189
  end
194
190
 
195
- send_ok(iq) if iq.is_a?(Jabber::Iq)
196
- end
197
-
198
- def get_subscriptions
199
- @pubsub = Jabber::PubSub::ServiceHelper.new(self, config['pubsub'])
200
- subs = @pubsub.get_subscriptions_from_all_nodes
201
- puts "SUBSCRIPTIONS: #{subs.inspect}"
202
- subs
203
- end
204
-
205
- def unsubscribe_all
206
- subscriptions = get_subscriptions
207
- return if !@pubsub
208
- subscriptions.each do |sub|
209
- @pubsub.unsubscribe_from(sub.node, sub.subid)
210
- end
191
+ #send_ok(iq) if iq.is_a?(Jabber::Iq)
211
192
  end
212
193
 
213
194
  ##
@@ -2,8 +2,8 @@ module C3s
2
2
  class ComponentConnection
3
3
  def initialize(componentclass, options={})
4
4
  @no_db = options[:no_db]
5
- if !componentclass.superclass.eql?(C3s::Component)
6
- puts "ERROR: #{componentclass} is not a valid C3s::Component!"
5
+ if !componentclass.superclass.eql?(C3s::Component) and !componentclass.superclass.eql?(C3s::Republisher)
6
+ puts "ERROR: #{componentclass} is not a valid C3s::Component (seems to be a #{componentclass.superclass})"
7
7
  exit
8
8
  end
9
9
 
@@ -16,7 +16,7 @@ module C3s
16
16
  @client_config.merge!('jid' => @client_config['name']+"."+@server_config['url'])
17
17
  @db_config = reader.section('db') if !@no_db
18
18
 
19
- puts "Creating new location component with jid '#{@client_config['jid']}'..."
19
+ puts "Creating new component with jid '#{@client_config['jid']}'..."
20
20
  @component = componentclass.new(@server_config.merge(@client_config))
21
21
  end
22
22
 
@@ -49,17 +49,17 @@ module C3s
49
49
  exit
50
50
  rescue Exception => e
51
51
  puts "ERROR: Couldn't connect to server!"
52
+ puts "#{e.inspect} #{e.backtrace.join("\n")}"
52
53
  $LOG.error "Couldn't connect to server!"
53
54
  exit
54
55
  end
55
56
  puts "External component #{@client_config['jid']} connected successfully."
56
57
 
57
- # TODO - never used?!
58
+ # TODO - use this to do something useful?
58
59
  @component.on_exception do |e, component, where|
59
- $LOG.error "**************FATAL ERROR"
60
- $LOG.error e.message
60
+ $LOG.error "************** FATAL ERROR"
61
61
  $LOG.error e.backtrace.join("\n")
62
- exit
62
+ #exit
63
63
  end
64
64
 
65
65
  puts "Starting messaging loop..."
data/lib/model.rb CHANGED
@@ -46,13 +46,11 @@ module C3sModel
46
46
  ##
47
47
  # Returns the first element for the model xml
48
48
  def first_element(options={})
49
- if options[:parent]
50
- first = options[:parent]
51
- else
52
- name = self._class_name
53
- name = name.pluralize if options[:plural]
54
- first = REXML::Element.new(name)
55
- end
49
+ return options[:parent] if options[:parent]
50
+
51
+ name = self._class_name
52
+ name = name.pluralize if options[:plural]
53
+ REXML::Element.new(name)
56
54
  end
57
55
 
58
56
  ##
data/lib/pubsub/node.rb CHANGED
@@ -13,11 +13,11 @@ module C3s
13
13
  @provider = provider
14
14
 
15
15
  if @jid.nil? and @provider
16
- @provider, @node, @domain, @resource = @provider.to_s.scan(PATTERN).first
17
- @jid = Jabber::JID.new(@node, @domain, @resource)
16
+ @provider, node, domain, resource = @provider.to_s.scan(PATTERN).first
17
+ @jid = Jabber::JID.new(node, domain, resource)
18
18
  end
19
19
 
20
- @provider.downcase! if @provider
20
+ @jid.resource = "default" if !resource and @jid
21
21
  end
22
22
 
23
23
  ##
@@ -38,6 +38,12 @@ module C3s
38
38
  @jid.resource
39
39
  end
40
40
 
41
+ ##
42
+ # Sets the resource for the node jid
43
+ def resource=(res)
44
+ @jid.resource = res.to_s
45
+ end
46
+
41
47
  ##
42
48
  # Checks if a node is a leaf node on c3s pubsub
43
49
  def leaf?
@@ -6,18 +6,25 @@ module C3s
6
6
 
7
7
  ##
8
8
  # Adds a node to the existing nodes
9
- # node::[String] the node name
9
+ # node:: [String] the node name
10
10
  def self.add_node(node)
11
11
  @@existing_nodes << node
12
12
  end
13
13
 
14
14
  ##
15
15
  # Checks if a node already exists on node list
16
- # node::[String] the node name
16
+ # node:: [String] the node name
17
17
  def self.include?(node)
18
18
  @@existing_nodes.include?(node)
19
19
  end
20
20
 
21
+ ##
22
+ # Removes a node from the node list
23
+ # node:: [String] the node name
24
+ def self.remove_node(node)
25
+ @@existing_nodes.delete(node)
26
+ end
27
+
21
28
  ##
22
29
  # Returns the existing nodes
23
30
  def self.nodes
@@ -1,5 +1,6 @@
1
1
  require 'xmpp4r/pubsub'
2
2
  require 'pubsub/nodetracker'
3
+ require 'pubsub/node'
3
4
 
4
5
  module C3s
5
6
  class Publisher
@@ -15,23 +16,16 @@ module C3s
15
16
 
16
17
  ##
17
18
  # Creates the collection node(s) and leaf node if needed
18
- # nodetree:: [String] node tree (eg: location:user@jabber.com/resource)
19
- def create_nodes(nodetree)
20
- nodes = nodetree.split(":")
21
-
22
- # build array like this one:
23
- # ['location', 'user@jabber.com', 'user@jabber.com/resource']
24
- nodes.insert(1, nodes.last.split("/").first)
25
-
26
- collection = nodes.shift # collection (eg: location)
27
- subcollection = "#{collection}:#{nodes.shift}" # subcollection (eg: location:user@jabber.com)
28
- leaf = "#{collection}:#{nodes.shift}" # leaf node name (eg: location:user@jabber.com/resource)
29
- leaf << "/default" unless leaf.match(/.*\/.*/)
19
+ # c3snode:: [C3s::Node] c3s pubsub node (eg: location:user@jabber.com/resource)
20
+ def create_tree(c3snode)
21
+ provider = c3snode.provider # provider (eg: location)
22
+ collection = "#{provider}:#{c3snode.jid.bare.to_s}" # collection (eg: location:user@jabber.com)
23
+ leaf = c3snode.to_s # leaf (eg: location:user@jabber.com/default)
30
24
 
31
25
  # create nodes
32
- create_node(collection, {:collection => true})
33
- create_node(subcollection, {:father => collection, :collection => true})
34
- create_node(leaf, {:father => subcollection, :collection => false})
26
+ create_node(provider, {:collection => true})
27
+ create_node(collection, {:father => provider, :collection => true})
28
+ create_node(leaf, {:father => collection, :collection => false})
35
29
  end
36
30
 
37
31
  ##
@@ -58,6 +52,14 @@ module C3s
58
52
  grant_owner_to_admin(node)
59
53
  end
60
54
 
55
+ ##
56
+ # Deletes a pubsub node
57
+ # nodename:: [String] the node name
58
+ # TODO: i should delete all leaf nodes inside a collection node!
59
+ def delete_node(nodename)
60
+ @pubsub.delete_node(nodename)
61
+ end
62
+
61
63
  ##
62
64
  # Creates the collection node if needed
63
65
  # name:: [String] collection node name
@@ -90,13 +92,10 @@ module C3s
90
92
  # Publishes content to the leaf node
91
93
  # node:: [String] the node to plublish to
92
94
  # content:: [REXML::Element] content xml to publish into node
93
- def publish(node, content)
95
+ def publish(c3snode, content)
94
96
  item = Jabber::PubSub::Item.new
95
97
  item.add(content)
96
-
97
- node << "/default" unless node.match(/.*\/.*/)
98
- node = [@client.config['name'], node].join(":")
99
- @pubsub.publish_item_to(node, item)
98
+ @pubsub.publish_item_to(c3snode.to_s, item)
100
99
  end
101
100
 
102
101
  ##
@@ -107,8 +106,6 @@ module C3s
107
106
  return true if NodeTracker.include?(name)
108
107
  nodebrowser = Jabber::PubSub::NodeBrowser.new(@client)
109
108
  nodebrowser.get_info(@service, name)
110
- # TODO this could be used instead
111
- # nodebrowser.nodes(@client.jid).include?(name)
112
109
  NodeTracker.add_node(name)
113
110
  true
114
111
  rescue Jabber::ServerError => error
@@ -17,12 +17,12 @@ module C3s
17
17
  ##
18
18
  # Subscribes to collection node.
19
19
  # nodename:: [String] the node name
20
- def subscribe_collection(nodename)
20
+ def subscribe_collection(nodename, options={})
21
21
  return if !is_collection?(nodename)
22
22
  subscription = @pubsub.subscribe_to(nodename)
23
23
  options = {
24
- 'pubsub#subscription_type' => 'items',
25
- 'pubsub#subscription_depth' => 'all'
24
+ 'pubsub#subscription_type' => options[:subscription_type] || 'items',
25
+ 'pubsub#subscription_depth' => options[:subscription_depth] || 'all'
26
26
  }
27
27
  @pubsub.set_options_for(nodename, @client.jid, options, subscription.subid)
28
28
  end
@@ -30,8 +30,9 @@ module C3s
30
30
  ##
31
31
  # Unsubscribe node
32
32
  # nodename:: [String] the node name
33
- def unsubscribe_from(nodename)
34
- @pubsub.unsubscribe_from(nodename)
33
+ # subid:: [String] the subscription ID
34
+ def unsubscribe_from(nodename, subid)
35
+ @pubsub.unsubscribe_from(nodename, subid)
35
36
  end
36
37
 
37
38
  ##
@@ -48,5 +49,35 @@ module C3s
48
49
  def get_last_item(nodename)
49
50
  @pubsub.get_items_from(nodename, 1)
50
51
  end
52
+
53
+ ##
54
+ # Returns all the subscriptions
55
+ def get_subscriptions
56
+ @pubsub.get_subscriptions_from_all_nodes
57
+ end
58
+
59
+ ##
60
+ # Unsubscribes all subscribed nodes
61
+ def unsubscribe_all
62
+ get_subscriptions().each do |sub|
63
+ unsubscribe_from(sub.node, sub.subid)
64
+ end
65
+ end
66
+
67
+ ##
68
+ # TODO - THIS NEEDED A @disco OBJECT.. AND I DON'T REMEMBER
69
+ # THE CLASS OF THE OBJECT
70
+ # Gets the leaf nodes for a given provider node. If the provider
71
+ # node is 'location' then the leaf nodes will be in the form
72
+ # 'location:person@domain.com/resource'
73
+ def get_leaf_nodes(firstnode, jid)
74
+ return if firstnode.nil? or @disco.nil?
75
+ firstnode.items.each do |item|
76
+ node = @disco.get_items_for(config['pubsub'], item.node)
77
+ c3snode = C3s::Node.new(item.node)
78
+ @items << item if c3snode.leaf? and jid==c3snode.jid
79
+ get_leaf_nodes(node, jid) unless node.items.size<1 or item.node.nil?
80
+ end
81
+ end
51
82
  end
52
83
  end
@@ -0,0 +1,83 @@
1
+ require 'component'
2
+ require 'pubsub/subscriber'
3
+
4
+ module C3s
5
+ class Republisher < C3s::Component
6
+ ##
7
+ # Starts the component and sets the subscribing nodes.
8
+ # subscribing_nodes:: [String or Array] the subscribing node(s)
9
+ def start(subscribing_nodes)
10
+ @subscribing_nodes = subscribing_nodes.to_a
11
+ @subscriber = C3s::Subscriber.new(self, config['pubsub'])
12
+ super()
13
+ end
14
+
15
+ ##
16
+ # Block the set iqs because this provider doesn't receive iq's
17
+ # directly to set the information.
18
+ def handle_iq(iq)
19
+ if iq.type == :set
20
+ puts "WARNING: IQ of type 'set' received from #{iq.from}!"
21
+ $LOG.warn("IQ of type 'set' received from #{iq.from}")
22
+ send_error(iq, ['unexpected-request', nil])
23
+ return
24
+ end
25
+ super
26
+ end
27
+
28
+ ##
29
+ # Handles messages. This can be subscribe or unsubscribe messages
30
+ # and pubsub events (most likely).
31
+ def handle_msg(msg)
32
+ puts "----------------- MESSAGE -------------------"
33
+ puts "#{msg.inspect}"
34
+ puts "----------------- MESSAGE -------------------"
35
+ if msg.body.eql?("sub")
36
+ @subscribing_nodes.each { |node| @subscriber.subscribe_collection(node) }
37
+ elsif msg.body.eql?("unsub")
38
+ @subscriber.unsubscribe_all
39
+ else
40
+ event = msg.first_element("event")
41
+ if event.kind_of?(Jabber::PubSub::Event)
42
+ event.each_element("//item/") do |item|
43
+ $LOG.debug("Received item from pubsub")
44
+ begin
45
+ c3snode = C3s::Node.new(item.attributes['node'])
46
+ next unless c3snode
47
+ $LOG.debug("Node built: #{c3snode.to_s}")
48
+ c3snode.provider = config['name'] # TODO - assuming that provider_name.eql?(pubsub_root_node)
49
+ $LOG.debug("Call republish() from child")
50
+
51
+
52
+ Thread.abort_on_exception = true
53
+ t = Thread.new do
54
+ republish(c3snode, item)
55
+ end
56
+ t.join
57
+ rescue Exception => e
58
+ $LOG.error "Error on published item: #{e}"
59
+ end
60
+ end
61
+ end
62
+ end
63
+ rescue Exception => e
64
+ $LOG.error "Error on handle_msg(): #{e.inspect} #{e.backtrace.join("\n")}"
65
+ end
66
+
67
+ ##
68
+ # Builds an object information based on pubsub item content. Each
69
+ # field of the published item is maped to an object attribute.
70
+ # klass:: [Class] the object class
71
+ # item:: [REXML::Element] the published item
72
+ def build_object(klass, item)
73
+ return nil if item.nil?
74
+ @object = klass.new
75
+ klass.attributes.each do |att|
76
+ @object.send("#{att}=", item.first_element(att).text)
77
+ end
78
+ @object
79
+ rescue Exception => e
80
+ $LOG.error "Error on build_object(): #{e.inspect} #{e.backtrace.join("\n")}"
81
+ end
82
+ end
83
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: c3s
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 3
8
+ - 3
9
+ version: 0.3.3
5
10
  platform: ruby
6
11
  authors:
7
12
  - Ricardo Otero
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-02-11 00:00:00 +00:00
17
+ date: 2010-03-03 00:00:00 +00:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -32,6 +37,7 @@ extra_rdoc_files:
32
37
  - lib/pubsub/nodetracker.rb
33
38
  - lib/pubsub/publisher.rb
34
39
  - lib/pubsub/subscriber.rb
40
+ - lib/republisher.rb
35
41
  files:
36
42
  - Manifest
37
43
  - README.rdoc
@@ -48,6 +54,7 @@ files:
48
54
  - lib/pubsub/nodetracker.rb
49
55
  - lib/pubsub/publisher.rb
50
56
  - lib/pubsub/subscriber.rb
57
+ - lib/republisher.rb
51
58
  - c3s.gemspec
52
59
  has_rdoc: true
53
60
  homepage: http://github.com/rikas/c3s
@@ -67,18 +74,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
67
74
  requirements:
68
75
  - - ">="
69
76
  - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
70
79
  version: "0"
71
- version:
72
80
  required_rubygems_version: !ruby/object:Gem::Requirement
73
81
  requirements:
74
82
  - - ">="
75
83
  - !ruby/object:Gem::Version
84
+ segments:
85
+ - 1
86
+ - 2
76
87
  version: "1.2"
77
- version:
78
88
  requirements: []
79
89
 
80
90
  rubyforge_project: c3s
81
- rubygems_version: 1.3.5
91
+ rubygems_version: 1.3.6
82
92
  signing_key:
83
93
  specification_version: 3
84
94
  summary: C3s library gem.