c3s 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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.