gnip 0.4.2

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.
Files changed (89) hide show
  1. data/README +144 -0
  2. data/Rakefile +53 -0
  3. data/TODO +72 -0
  4. data/bin/gnip +651 -0
  5. data/doc/api.html +1201 -0
  6. data/gemspec.rb +47 -0
  7. data/gnip-0.4.2.gem +0 -0
  8. data/lib/gnip.rb +71 -0
  9. data/lib/gnip/activity.rb +663 -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 +304 -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 +309 -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/helper.rb.bak +28 -0
  34. data/test/integration/auth.rb +12 -0
  35. data/test/integration/publisher.rb +86 -0
  36. data/test/lib/shoulda.rb +9 -0
  37. data/test/lib/shoulda/action_controller.rb +28 -0
  38. data/test/lib/shoulda/action_controller/helpers.rb +47 -0
  39. data/test/lib/shoulda/action_controller/macros.rb +277 -0
  40. data/test/lib/shoulda/action_controller/matchers.rb +37 -0
  41. data/test/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
  42. data/test/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
  43. data/test/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
  44. data/test/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
  45. data/test/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +77 -0
  46. data/test/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  47. data/test/lib/shoulda/action_controller/matchers/set_session_matcher.rb +83 -0
  48. data/test/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
  49. data/test/lib/shoulda/action_mailer.rb +10 -0
  50. data/test/lib/shoulda/action_mailer/assertions.rb +38 -0
  51. data/test/lib/shoulda/action_view.rb +10 -0
  52. data/test/lib/shoulda/action_view/macros.rb +56 -0
  53. data/test/lib/shoulda/active_record.rb +16 -0
  54. data/test/lib/shoulda/active_record/assertions.rb +69 -0
  55. data/test/lib/shoulda/active_record/helpers.rb +40 -0
  56. data/test/lib/shoulda/active_record/macros.rb +586 -0
  57. data/test/lib/shoulda/active_record/matchers.rb +42 -0
  58. data/test/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
  59. data/test/lib/shoulda/active_record/matchers/allow_value_matcher.rb +102 -0
  60. data/test/lib/shoulda/active_record/matchers/association_matcher.rb +226 -0
  61. data/test/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
  62. data/test/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
  63. data/test/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
  64. data/test/lib/shoulda/active_record/matchers/have_index_matcher.rb +105 -0
  65. data/test/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +125 -0
  66. data/test/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
  67. data/test/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
  68. data/test/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
  69. data/test/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
  70. data/test/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
  71. data/test/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
  72. data/test/lib/shoulda/assertions.rb +59 -0
  73. data/test/lib/shoulda/autoload_macros.rb +46 -0
  74. data/test/lib/shoulda/context.rb +304 -0
  75. data/test/lib/shoulda/helpers.rb +8 -0
  76. data/test/lib/shoulda/macros.rb +73 -0
  77. data/test/lib/shoulda/private_helpers.rb +20 -0
  78. data/test/lib/shoulda/proc_extensions.rb +14 -0
  79. data/test/lib/shoulda/rails.rb +13 -0
  80. data/test/lib/shoulda/rspec.rb +9 -0
  81. data/test/lib/shoulda/tasks.rb +3 -0
  82. data/test/lib/shoulda/tasks/list_tests.rake +29 -0
  83. data/test/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
  84. data/test/lib/shoulda/test_unit.rb +19 -0
  85. data/test/lib/xmlsimple.rb +1021 -0
  86. data/test/loader.rb +25 -0
  87. data/test/unit/activity.rb +26 -0
  88. data/test/unit/util.rb +39 -0
  89. metadata +198 -0
data/lib/gnip/list.rb ADDED
@@ -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,309 @@
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
+
216
+ buckets =
217
+ if thru
218
+ thru = 0 if thru =~ /current|now/i
219
+ a, b = [ago, Integer(thru)].sort
220
+ (a..b).to_a.reverse.map{|i| bucket_for_minutes_ago(i)}
221
+ else
222
+ if bucket =~ /all/i
223
+ stream = send("#{ style }_stream")
224
+ stream.buckets.map{|bucket| File.basename(bucket, '.xml')}
225
+ else
226
+ [bucket]
227
+ end
228
+ end
229
+
230
+ activities = []
231
+
232
+ msg = buckets.size > 1 ? 'threadify' : 'each'
233
+
234
+ buckets.send(msg) do |bucket|
235
+ path = "#{ style }/#{ bucket }.xml"
236
+ path = "filters/#{ filter }/#{ path }" if filter
237
+ xml = resource[path].get
238
+ list = Activity.list_from_xml(xml, &block)
239
+ activities.push(*list) unless block
240
+ end
241
+
242
+ activities unless block
243
+ end
244
+
245
+ def bucket_for_minutes_ago ago
246
+ bucket = Gnip.time - (Integer(ago) * 60)
247
+ bucket.strftime('%Y%m%d%H%M')
248
+ end
249
+
250
+ def notification_stream options = {}
251
+ Activity.stream(options.update(:publisher => self, :scope => scope, :style => 'notification'))
252
+ end
253
+
254
+ def notifications options = {}
255
+ Gnip.optify!(options)
256
+ options.setopt!(:style, 'notification') unless options.hasopt?(:style)
257
+ activity(options)
258
+ end
259
+
260
+ def publish *activities
261
+ activities.flatten!
262
+ activities.compact!
263
+ #xml = "<activiies>#{ activities.map{|activity| activity.to_xml} }</activities>"
264
+ xml = tagz { activities_{ activities.map{|activity| activity.to_xml(tagz.doc)} } }
265
+ resource['activity.xml'].post(xml)
266
+ activities
267
+ end
268
+
269
+
270
+ def filter
271
+ @filter ||= FilterResource.new(self)
272
+ end
273
+
274
+ class FilterResource
275
+ attr_accessor :publisher
276
+
277
+ def initialize publisher
278
+ @publisher = publisher
279
+ end
280
+
281
+ def resource
282
+ publisher.resource
283
+ end
284
+
285
+ def list
286
+ xml = resource['filters.xml'].get
287
+ Filter.list_from_xml(xml).each{|filter| filter.publisher = publisher}
288
+ end
289
+
290
+ def for name
291
+ xml = resource["filters/#{ name }.xml"].get
292
+ filter = Filter.from_xml(xml)
293
+ ensure
294
+ filter.publisher = publisher if filter
295
+ end
296
+
297
+ alias_method '[]', 'for'
298
+
299
+ def create(name, rules, options)
300
+ Gnip.optify!(options)
301
+ filter = Filter.new(name, rules, options)
302
+ resource['filters.xml'].post(filter.to_xml(:declaration => true))
303
+ filter = self.for(name)
304
+ ensure
305
+ filter.publisher = publisher if filter
306
+ end
307
+ end
308
+ end
309
+ end