gnip-gnip 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/README +144 -0
  2. data/Rakefile +221 -0
  3. data/TODO +72 -0
  4. data/bin/gnip +651 -0
  5. data/doc/api.html +1201 -0
  6. data/gemspec.rb +25 -0
  7. data/gnip-ruby.gemspec +26 -0
  8. data/lib/gnip.rb +71 -0
  9. data/lib/gnip/activity.rb +665 -0
  10. data/lib/gnip/api.rb +191 -0
  11. data/lib/gnip/arguments.rb +21 -0
  12. data/lib/gnip/blankslate.rb +5 -0
  13. data/lib/gnip/config.rb +144 -0
  14. data/lib/gnip/filter.rb +311 -0
  15. data/lib/gnip/list.rb +126 -0
  16. data/lib/gnip/options.rb +96 -0
  17. data/lib/gnip/orderedhash.rb +199 -0
  18. data/lib/gnip/publisher.rb +316 -0
  19. data/lib/gnip/resource.rb +301 -0
  20. data/lib/gnip/template.rb +44 -0
  21. data/lib/gnip/util.rb +120 -0
  22. data/sample/data/activity.yml +21 -0
  23. data/test/auth.rb +60 -0
  24. data/test/config.yml +2 -0
  25. data/test/data/activity.xml +14 -0
  26. data/test/data/activity_only_required.xml +4 -0
  27. data/test/data/activity_with_payload.xml +22 -0
  28. data/test/data/activity_with_place.xml +18 -0
  29. data/test/data/activity_with_place_wo_bounds.xml +36 -0
  30. data/test/data/activity_with_unbounded_media_urls.xml +44 -0
  31. data/test/data/activity_without_bounds.xml +24 -0
  32. data/test/helper.rb +115 -0
  33. data/test/integration/auth.rb +12 -0
  34. data/test/integration/publisher.rb +86 -0
  35. data/test/lib/shoulda.rb +9 -0
  36. data/test/lib/shoulda/action_controller.rb +28 -0
  37. data/test/lib/shoulda/action_controller/helpers.rb +47 -0
  38. data/test/lib/shoulda/action_controller/macros.rb +277 -0
  39. data/test/lib/shoulda/action_controller/matchers.rb +37 -0
  40. data/test/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
  41. data/test/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
  42. data/test/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
  43. data/test/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
  44. data/test/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +77 -0
  45. data/test/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  46. data/test/lib/shoulda/action_controller/matchers/set_session_matcher.rb +83 -0
  47. data/test/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
  48. data/test/lib/shoulda/action_mailer.rb +10 -0
  49. data/test/lib/shoulda/action_mailer/assertions.rb +38 -0
  50. data/test/lib/shoulda/action_view.rb +10 -0
  51. data/test/lib/shoulda/action_view/macros.rb +56 -0
  52. data/test/lib/shoulda/active_record.rb +16 -0
  53. data/test/lib/shoulda/active_record/assertions.rb +69 -0
  54. data/test/lib/shoulda/active_record/helpers.rb +40 -0
  55. data/test/lib/shoulda/active_record/macros.rb +586 -0
  56. data/test/lib/shoulda/active_record/matchers.rb +42 -0
  57. data/test/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
  58. data/test/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
  59. data/test/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
  60. data/test/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
  61. data/test/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
  62. data/test/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
  63. data/test/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
  64. data/test/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
  65. data/test/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
  66. data/test/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
  67. data/test/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
  68. data/test/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
  69. data/test/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
  70. data/test/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
  71. data/test/lib/shoulda/assertions.rb +59 -0
  72. data/test/lib/shoulda/autoload_macros.rb +46 -0
  73. data/test/lib/shoulda/context.rb +304 -0
  74. data/test/lib/shoulda/helpers.rb +8 -0
  75. data/test/lib/shoulda/macros.rb +73 -0
  76. data/test/lib/shoulda/private_helpers.rb +20 -0
  77. data/test/lib/shoulda/proc_extensions.rb +14 -0
  78. data/test/lib/shoulda/rails.rb +13 -0
  79. data/test/lib/shoulda/rspec.rb +9 -0
  80. data/test/lib/shoulda/tasks.rb +3 -0
  81. data/test/lib/shoulda/tasks/list_tests.rake +29 -0
  82. data/test/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
  83. data/test/lib/shoulda/test_unit.rb +19 -0
  84. data/test/lib/xmlsimple.rb +1021 -0
  85. data/test/loader.rb +25 -0
  86. data/test/unit/activity.rb +26 -0
  87. data/test/unit/util.rb +39 -0
  88. metadata +158 -0
@@ -0,0 +1,126 @@
1
+ module Gnip
2
+ # a typed list of objects
3
+ #
4
+ class List
5
+ include Enumerable
6
+ include Comparable
7
+
8
+ def List.for(klass, *args, &block)
9
+ new(klass, *args, &block)
10
+ end
11
+
12
+ def List.of(klass, *args, &block)
13
+ new(klass, *args, &block)
14
+ end
15
+
16
+ attr :list
17
+ attr :klass
18
+
19
+ def initialize(klass, *args, &block)
20
+ @list = []
21
+ @klass = klass
22
+ end
23
+
24
+ def new(*args, &block)
25
+ if klass.respond_to?(:for)
26
+ klass.for(*args, &block)
27
+ else
28
+ klass.new(*args, &block)
29
+ end
30
+ end
31
+
32
+ def cast(value)
33
+ return value if value.is_a?(klass)
34
+ msg =
35
+ if klass.respond_to?(:cast)
36
+ :cast
37
+ elsif klass.respond_to?(:for)
38
+ :for
39
+ else
40
+ :new
41
+ end
42
+ klass.send(msg, value)
43
+ end
44
+
45
+ def build(*args, &block)
46
+ element = new(*args, &block)
47
+ list << element
48
+ element
49
+ end
50
+ alias_method 'create', 'build'
51
+
52
+ def push(value)
53
+ list << cast(value)
54
+ self
55
+ end
56
+ alias_method '<<', 'push'
57
+
58
+ def each(&block)
59
+ list.each(&block)
60
+ end
61
+
62
+ def map(&block)
63
+ list.map(&block)
64
+ end
65
+
66
+ def [](idx)
67
+ list[idx]
68
+ end
69
+
70
+ def inspect
71
+ "#{ self.class.name }.of(#{ klass.name })#{ list.inspect }"
72
+ end
73
+
74
+ def clear
75
+ list.clear
76
+ self
77
+ end
78
+
79
+ def size
80
+ list.size
81
+ end
82
+
83
+ def replace other
84
+ clear
85
+ case other
86
+ when List, Array
87
+ other.flatten.each{|value| push(value)}
88
+ else
89
+ push(other)
90
+ end
91
+ self
92
+ end
93
+
94
+ def first
95
+ list.first
96
+ end
97
+
98
+ def last
99
+ list.last
100
+ end
101
+
102
+ def to_a
103
+ list
104
+ end
105
+
106
+ def to_xs
107
+ to_a.map{|element| element.respond_to?(:to_xs) ? element.to_xs : element}
108
+ end
109
+
110
+ def method_missing(m, *a, &b)
111
+ if list.respond_to?(m)
112
+ list.send(m, *a, &b)
113
+ else
114
+ super
115
+ end
116
+ end
117
+
118
+ def to_yaml(*a, &b)
119
+ list.to_yaml(*a, &b)
120
+ end
121
+
122
+ def <=> other
123
+ list <=> other
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,96 @@
1
+ module Gnip
2
+ module Options
3
+ def to_options!
4
+ replace to_options
5
+ end
6
+
7
+ def to_options
8
+ keys.inject(Hash.new){|h,k| h.update k.to_s.to_sym => fetch(k)}
9
+ end
10
+
11
+ def getopt key, default = nil
12
+ [ key ].flatten.each do |key|
13
+ return fetch(key) if has_key?(key)
14
+ key = key.to_s
15
+ return fetch(key) if has_key?(key)
16
+ key = key.to_sym
17
+ return fetch(key) if has_key?(key)
18
+ end
19
+ default
20
+ end
21
+
22
+ def getopts *args
23
+ args.flatten.map{|arg| getopt arg}
24
+ end
25
+
26
+ def hasopt key, default = nil
27
+ [ key ].flatten.each do |key|
28
+ return true if has_key?(key)
29
+ key = key.to_s
30
+ return true if has_key?(key)
31
+ key = key.to_sym
32
+ return true if has_key?(key)
33
+ end
34
+ default
35
+ end
36
+ alias_method 'hasopt?', 'hasopt'
37
+
38
+ def hasopts *args
39
+ args.flatten.map{|arg| hasopt arg}
40
+ end
41
+ alias_method 'hasopts?', 'hasopts'
42
+
43
+ def delopt key, default = nil
44
+ [ key ].flatten.each do |key|
45
+ return delete(key) if has_key?(key)
46
+ key = key.to_s
47
+ return delete(key) if has_key?(key)
48
+ key = key.to_sym
49
+ return delete(key) if has_key?(key)
50
+ end
51
+ default
52
+ end
53
+
54
+ def delopts *args
55
+ args.flatten.map{|arg| delopt arg}
56
+ end
57
+
58
+ def setopt key, value = nil
59
+ [ key ].flatten.each do |key|
60
+ return self[key]=value if has_key?(key)
61
+ key = key.to_s
62
+ return self[key]=value if has_key?(key)
63
+ key = key.to_sym
64
+ return self[key]=value if has_key?(key)
65
+ end
66
+ return self[key]=value
67
+ end
68
+ alias_method 'setopt!', 'setopt'
69
+
70
+ def setopts opts
71
+ opts.each{|key, value| setopt key, value}
72
+ opts
73
+ end
74
+ alias_method 'setopts!', 'setopts'
75
+
76
+ def select! *a, &b
77
+ replace select(*a, &b).to_hash
78
+ end
79
+ end
80
+
81
+ def Options.for(hash)
82
+ hash =
83
+ case hash
84
+ when Hash
85
+ hash
86
+ when Array
87
+ Hash[*hash.flatten]
88
+ when String, Symbol
89
+ {hash => true}
90
+ else
91
+ hash.to_hash
92
+ end
93
+ ensure
94
+ hash.extend(Options) unless hash.is_a?(Options)
95
+ end
96
+ end
@@ -0,0 +1,199 @@
1
+
2
+ # AUTHOR
3
+ # jan molic /mig/at/1984/dot/cz/
4
+ #
5
+ # DESCRIPTION
6
+ # Hash with preserved order and some array-like extensions
7
+ # Public domain.
8
+ #
9
+ # THANKS
10
+ # Andrew Johnson for his suggestions and fixes of Hash[],
11
+ # merge, to_a, inspect and shift
12
+
13
+ module Gnip
14
+ class OrderedHash < ::Hash
15
+ attr_accessor :order
16
+
17
+ class << self
18
+ def [] *args
19
+ hsh = OrderedHash.new
20
+ if Hash === args[0]
21
+ hsh.replace args[0]
22
+ elsif (args.size % 2) != 0
23
+ raise ArgumentError, "odd number of elements for Hash"
24
+ else
25
+ 0.step(args.size - 1, 2) do |a|
26
+ b = a + 1
27
+ hsh[args[a]] = args[b]
28
+ end
29
+ end
30
+ hsh
31
+ end
32
+ end
33
+ def initialize(*a, &b)
34
+ super
35
+ @order = []
36
+ end
37
+ def store_only a,b
38
+ store a,b
39
+ end
40
+ alias orig_store store
41
+ def store a,b
42
+ @order.push a unless has_key? a
43
+ super a,b
44
+ end
45
+ alias []= store
46
+ def == hsh2
47
+ return false if @order != hsh2.order
48
+ super hsh2
49
+ end
50
+ def clear
51
+ @order = []
52
+ super
53
+ end
54
+ def delete key
55
+ @order.delete key
56
+ super
57
+ end
58
+ def each_key
59
+ @order.each { |k| yield k }
60
+ self
61
+ end
62
+ def each_value
63
+ @order.each { |k| yield self[k] }
64
+ self
65
+ end
66
+ def each
67
+ @order.each { |k| yield k,self[k] }
68
+ self
69
+ end
70
+ alias each_pair each
71
+ def delete_if
72
+ @order.clone.each { |k|
73
+ delete k if yield(k)
74
+ }
75
+ self
76
+ end
77
+ def values
78
+ ary = []
79
+ @order.each { |k| ary.push self[k] }
80
+ ary
81
+ end
82
+ def keys
83
+ @order
84
+ end
85
+ def first
86
+ {@order.first => self[@order.first]}
87
+ end
88
+ def last
89
+ {@order.last => self[@order.last]}
90
+ end
91
+ def invert
92
+ hsh2 = Hash.new
93
+ @order.each { |k| hsh2[self[k]] = k }
94
+ hsh2
95
+ end
96
+ def reject(&block)
97
+ self.dup.delete_if(&block)
98
+ end
99
+ def reject!(&block)
100
+ hsh2 = reject(&block)
101
+ self == hsh2 ? nil : hsh2
102
+ end
103
+ def replace hsh2
104
+ @order = hsh2.keys
105
+ super hsh2
106
+ end
107
+ def shift
108
+ key = @order.first
109
+ key ? [key,delete(key)] : super
110
+ end
111
+ def unshift k,v
112
+ unless self.include? k
113
+ @order.unshift k
114
+ orig_store(k,v)
115
+ true
116
+ else
117
+ false
118
+ end
119
+ end
120
+ def push k,v
121
+ unless self.include? k
122
+ @order.push k
123
+ orig_store(k,v)
124
+ true
125
+ else
126
+ false
127
+ end
128
+ end
129
+ def pop
130
+ key = @order.last
131
+ key ? [key,delete(key)] : nil
132
+ end
133
+ def to_a
134
+ ary = []
135
+ each { |k,v| ary << [k,v] }
136
+ ary
137
+ end
138
+ def to_s
139
+ self.to_a.to_s
140
+ end
141
+ def inspect
142
+ ary = []
143
+ each {|k,v| ary << k.inspect + "=>" + v.inspect}
144
+ '{' + ary.join(", ") + '}'
145
+ end
146
+ def update hsh2
147
+ hsh2.each { |k,v| self[k] = v }
148
+ self
149
+ end
150
+ alias :merge! update
151
+ def merge hsh2
152
+ self.dup update(hsh2)
153
+ end
154
+ def select
155
+ ary = []
156
+ each { |k,v| ary << [k,v] if yield k,v }
157
+ ary
158
+ end
159
+ def class
160
+ Hash
161
+ end
162
+ def __class__
163
+ OrderedHash
164
+ end
165
+
166
+ attr_accessor "to_yaml_style"
167
+ def yaml_inline= bool
168
+ if respond_to?("to_yaml_style")
169
+ self.to_yaml_style = :inline
170
+ else
171
+ unless defined? @__yaml_inline_meth
172
+ @__yaml_inline_meth =
173
+ lambda {|opts|
174
+ YAML::quick_emit(object_id, opts) {|emitter|
175
+ emitter << '{ ' << map{|kv| kv.join ': '}.join(', ') << ' }'
176
+ }
177
+ }
178
+ class << self
179
+ def to_yaml opts = {}
180
+ begin
181
+ @__yaml_inline ? @__yaml_inline_meth[ opts ] : super
182
+ rescue
183
+ @to_yaml_style = :inline
184
+ super
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+ @__yaml_inline = bool
191
+ end
192
+ def yaml_inline!() self.yaml_inline = true end
193
+
194
+ def each_with_index
195
+ @order.each_with_index { |k, index| yield k, self[k], index }
196
+ self
197
+ end
198
+ end # class OrderedHash
199
+ end
@@ -0,0 +1,316 @@
1
+ module Gnip
2
+ class Publisher
3
+ def Publisher.list(options = {})
4
+ options = Gnip.optify!(options)
5
+ scope = options.getopt(:scope, Gnip.scope)
6
+ resource = options.getopt(:resource, Gnip.default.resource)
7
+ endpoint = resource.endpoint "#{ scope }/publishers.xml"
8
+ response = endpoint.get
9
+ xml = response.to_s
10
+ Publisher.list_from_xml(xml, :scope => scope)
11
+ end
12
+
13
+ def Publisher.list_from_xml(xml, options = {}, &block)
14
+ list = []
15
+ parse_xml(xml, options) do |publisher|
16
+ block ? block.call(publisher) : list.push(publisher)
17
+ end
18
+ block ? nil : list
19
+ end
20
+
21
+ def Publisher.from_xml(xml, options = {}, &block)
22
+ parse_xml(xml, options){|publisher| return publisher}
23
+ end
24
+
25
+ def Publisher.parse_xml(xml, options = {}, &block)
26
+ doc = Nokogiri::XML.parse(xml)
27
+ list = []
28
+ selectors = '*/publishers', 'publisher'
29
+ selectors.each do |selector|
30
+ search = doc.search(selector)
31
+ next unless search.size > 0
32
+ search.each do |node|
33
+ publisher = Publisher.from_node(node, options)
34
+ block ? block.call(publisher) : list.push(publisher)
35
+ end
36
+ end
37
+ block ? nil : list
38
+ end
39
+
40
+ def Publisher.from_node(node, options = {})
41
+ name = node['name']
42
+ rules = node.search('supportedRuleTypes/type').map{|type| type.content}
43
+ Publisher.new(name, options.update(:rules => rules))
44
+ end
45
+
46
+ def Publisher.for name, options = {}
47
+ options = Gnip.optify!(options)
48
+ scope = options.getopt(:scope, Gnip.scope)
49
+ resource = options.getopt(:resource, Gnip.default.resource)
50
+ endpoint = resource["#{ scope }/publishers/#{ name }.xml"]
51
+ response = endpoint.get
52
+ xml = response.to_s
53
+ publisher = Publisher.from_xml(xml)
54
+ publisher.scope = scope
55
+ publisher
56
+ end
57
+
58
+ def Publisher.exists?(*args, &block)
59
+ Publisher.for(*args, &block) rescue false
60
+ end
61
+
62
+ def Publisher.resource
63
+ @resource ||= Gnip.default.resource
64
+ end
65
+
66
+ def Publisher.create(*args, &block)
67
+ publisher = new(*args, &block)
68
+ resource = Publisher.resource["#{ publisher.scope }/publishers.xml"]
69
+ resource.post(publisher.to_xml(:declaration => true))
70
+ Publisher.for(publisher.name, :scope => publisher.scope)
71
+ end
72
+
73
+ def Publisher.delete(name, options = {})
74
+ if publisher = Publisher.exists?(name, options)
75
+ publisher.delete
76
+ end
77
+ end
78
+
79
+ Attributes = []
80
+
81
+ Attributes << 'name'
82
+ def name
83
+ @name ||= nil
84
+ end
85
+ def name= value
86
+ @name = String(value)
87
+ ensure
88
+ raise ArgumentError, @name unless @name =~ %r/^[a-zA-Z0-9.+-]+$/
89
+ end
90
+
91
+ Attributes << 'rules'
92
+ def rules
93
+ @rules ||= List.of(String)
94
+ end
95
+ def rules= value
96
+ rules.replace(value)
97
+ end
98
+
99
+ attr_accessor :scope
100
+
101
+ def initialize(*args)
102
+ args, options = Gnip.args_for(args)
103
+ self.name = args.shift if args.first
104
+ @scope = options.getopt(:scope, Gnip.scope).to_s
105
+ @resource = options.getopt(:resource, Gnip.default.resource)
106
+ rules = options.getopt(:rules, []).flatten.compact
107
+ @rules = rules.map{|rule| Rule.for(rule)}
108
+ end
109
+
110
+ def resource
111
+ @resource["#{ scope }/publishers/#{ name }"]
112
+ end
113
+
114
+
115
+
116
+ class Rule < ::String
117
+ List = []
118
+
119
+ %w[ actor tag to regarding source keyword ].each do |name|
120
+ module_eval <<-code
121
+ def Rule.#{ name }
122
+ @#{ name } ||= Rule.new('#{ name }').freeze
123
+ end
124
+ code
125
+ List << Rule.send(name)
126
+ end
127
+
128
+ List.freeze
129
+
130
+ def Rule.list
131
+ List
132
+ end
133
+
134
+ def Rule.for(name)
135
+ send(name.to_s.downcase.strip)
136
+ rescue
137
+ raise ArgumentError, "bad rule type #{ name.inspect }"
138
+ end
139
+
140
+ def Rule.[] name
141
+ Rule.for(name)
142
+ end
143
+ end
144
+
145
+ def Publisher.rule
146
+ Rule
147
+ end
148
+
149
+ include Tagz
150
+ def to_xml(*args)
151
+ args, options = Gnip.args_for(args)
152
+ doc = args.first
153
+
154
+ tagz(doc) {
155
+ publisher_(:name => name){
156
+ supportedRuleTypes_{
157
+ rules.each{|rule| type_{ rule }}
158
+ }
159
+ }
160
+ }
161
+ end
162
+
163
+ =begin
164
+ def Publisher.template
165
+ @template ||=
166
+ Template.new do
167
+ "
168
+ <publisher name=<%= name.inspect %>>
169
+ <supportedRuleTypes>
170
+ % rules.each do |rule|
171
+ <type><%= rule %></type>
172
+ % end
173
+ </supportedRuleTypes>
174
+ </publisher>
175
+ "
176
+ end
177
+ end
178
+
179
+ def to_xml(options = {})
180
+ Publisher.template.expand(self)
181
+ end
182
+ =end
183
+
184
+
185
+ def delete
186
+ Publisher.resource["#{ scope }/publishers/#{ name }"].delete
187
+ self
188
+ end
189
+
190
+ def activity_stream options = {}
191
+ Activity.stream(options.update(:publisher => self, :scope => scope))
192
+ end
193
+
194
+ def activity options = {}, &block
195
+ Gnip.optify!(options)
196
+
197
+ style = options.getopt(:style, 'activity').to_s
198
+ raise ArgumentError unless %w( activity notification ).include?(style)
199
+
200
+
201
+ bucket = options.getopt(:bucket)
202
+ ago = options.getopt(:ago)
203
+ thru = options.getopt(:thru, options.getopt(:through))
204
+
205
+ if Range === ago
206
+ ago, thru = [ago.begin, ago.end].sort.reverse
207
+ end
208
+
209
+ unless bucket
210
+ bucket = ago ? bucket_for_minutes_ago(ago) : 'current'
211
+ end
212
+
213
+ filter = options.getopt(:filter)
214
+ filter = filter.value if(filter and filter.respond_to?(:value))
215
+ filter = filter.name if(filter and filter.respond_to?(:name))
216
+
217
+ buckets =
218
+ if thru
219
+ thru = 0 if thru =~ /current|now/i
220
+ a, b = [ago, Integer(thru)].sort
221
+ (a..b).to_a.reverse.map{|i| bucket_for_minutes_ago(i)}
222
+ else
223
+ if bucket =~ /all/i
224
+ stream = send("#{ style }_stream")
225
+ stream.buckets.map{|bucket| File.basename(bucket, '.xml')}
226
+ else
227
+ [bucket]
228
+ end
229
+ end
230
+
231
+ buckets.map! do |bucket|
232
+ bucket.is_a?(Time) ? bucket.strftime('%Y%m%d%H%M') : bucket
233
+ end
234
+
235
+ activities = []
236
+
237
+ msg = buckets.size > 1 ? 'threadify' : 'each'
238
+
239
+ buckets.send(msg) do |bucket|
240
+ path = "#{ style }/#{ bucket }.xml"
241
+ path = "filters/#{ filter }/#{ path }" if filter
242
+ xml = resource[path].get
243
+ Activity.list_from_xml(xml) do |activity|
244
+ activity.gnip_resource_uri = resource[path].uri
245
+ block ? block.call(activity) : activities.push(activity)
246
+ end
247
+ end
248
+
249
+ activities unless block
250
+ end
251
+
252
+ def bucket_for_minutes_ago ago
253
+ bucket = Gnip.time - (Integer(ago) * 60)
254
+ bucket.strftime('%Y%m%d%H%M')
255
+ end
256
+
257
+ def notification_stream options = {}
258
+ Activity.stream(options.update(:publisher => self, :scope => scope, :style => 'notification'))
259
+ end
260
+
261
+ def notifications options = {}
262
+ Gnip.optify!(options)
263
+ options.setopt!(:style, 'notification') unless options.hasopt?(:style)
264
+ activity(options)
265
+ end
266
+
267
+ def publish *activities
268
+ activities.flatten!
269
+ activities.compact!
270
+ #xml = "<activiies>#{ activities.map{|activity| activity.to_xml} }</activities>"
271
+ xml = tagz { activities_{ activities.map{|activity| activity.to_xml(tagz.doc)} } }
272
+ resource['activity.xml'].post(xml)
273
+ activities
274
+ end
275
+
276
+
277
+ def filter
278
+ @filter ||= FilterResource.new(self)
279
+ end
280
+
281
+ class FilterResource
282
+ attr_accessor :publisher
283
+
284
+ def initialize publisher
285
+ @publisher = publisher
286
+ end
287
+
288
+ def resource
289
+ publisher.resource
290
+ end
291
+
292
+ def list
293
+ xml = resource['filters.xml'].get
294
+ Filter.list_from_xml(xml).each{|filter| filter.publisher = publisher}
295
+ end
296
+
297
+ def for name
298
+ xml = resource["filters/#{ name }.xml"].get
299
+ filter = Filter.from_xml(xml)
300
+ ensure
301
+ filter.publisher = publisher if filter
302
+ end
303
+
304
+ alias_method '[]', 'for'
305
+
306
+ def create(name, rules, options)
307
+ Gnip.optify!(options)
308
+ filter = Filter.new(name, rules, options)
309
+ resource['filters.xml'].post(filter.to_xml(:declaration => true))
310
+ filter = self.for(name)
311
+ ensure
312
+ filter.publisher = publisher if filter
313
+ end
314
+ end
315
+ end
316
+ end