nelumba 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +9 -0
  3. data/Gemfile +20 -0
  4. data/README.md +242 -0
  5. data/Rakefile +7 -0
  6. data/assets/lotus_logo_purple.png +0 -0
  7. data/assets/lotus_logo_purple.svg +262 -0
  8. data/lib/nelumba.rb +47 -0
  9. data/lib/nelumba/activity.rb +250 -0
  10. data/lib/nelumba/application.rb +11 -0
  11. data/lib/nelumba/article.rb +11 -0
  12. data/lib/nelumba/atom/account.rb +50 -0
  13. data/lib/nelumba/atom/address.rb +56 -0
  14. data/lib/nelumba/atom/author.rb +176 -0
  15. data/lib/nelumba/atom/category.rb +41 -0
  16. data/lib/nelumba/atom/comment.rb +96 -0
  17. data/lib/nelumba/atom/entry.rb +216 -0
  18. data/lib/nelumba/atom/feed.rb +198 -0
  19. data/lib/nelumba/atom/generator.rb +40 -0
  20. data/lib/nelumba/atom/link.rb +79 -0
  21. data/lib/nelumba/atom/name.rb +57 -0
  22. data/lib/nelumba/atom/organization.rb +62 -0
  23. data/lib/nelumba/atom/person.rb +179 -0
  24. data/lib/nelumba/atom/portable_contacts.rb +117 -0
  25. data/lib/nelumba/atom/source.rb +179 -0
  26. data/lib/nelumba/atom/thread.rb +60 -0
  27. data/lib/nelumba/audio.rb +39 -0
  28. data/lib/nelumba/badge.rb +11 -0
  29. data/lib/nelumba/binary.rb +52 -0
  30. data/lib/nelumba/bookmark.rb +30 -0
  31. data/lib/nelumba/category.rb +49 -0
  32. data/lib/nelumba/collection.rb +34 -0
  33. data/lib/nelumba/comment.rb +47 -0
  34. data/lib/nelumba/crypto.rb +144 -0
  35. data/lib/nelumba/device.rb +11 -0
  36. data/lib/nelumba/discover.rb +362 -0
  37. data/lib/nelumba/event.rb +57 -0
  38. data/lib/nelumba/feed.rb +173 -0
  39. data/lib/nelumba/file.rb +43 -0
  40. data/lib/nelumba/generator.rb +53 -0
  41. data/lib/nelumba/group.rb +11 -0
  42. data/lib/nelumba/identity.rb +63 -0
  43. data/lib/nelumba/image.rb +30 -0
  44. data/lib/nelumba/link.rb +56 -0
  45. data/lib/nelumba/note.rb +34 -0
  46. data/lib/nelumba/notification.rb +229 -0
  47. data/lib/nelumba/object.rb +251 -0
  48. data/lib/nelumba/person.rb +306 -0
  49. data/lib/nelumba/place.rb +34 -0
  50. data/lib/nelumba/product.rb +30 -0
  51. data/lib/nelumba/publisher.rb +44 -0
  52. data/lib/nelumba/question.rb +30 -0
  53. data/lib/nelumba/review.rb +30 -0
  54. data/lib/nelumba/service.rb +11 -0
  55. data/lib/nelumba/subscription.rb +117 -0
  56. data/lib/nelumba/version.rb +3 -0
  57. data/lib/nelumba/video.rb +43 -0
  58. data/nelumba.gemspec +28 -0
  59. data/spec/activity_spec.rb +116 -0
  60. data/spec/application_spec.rb +136 -0
  61. data/spec/article_spec.rb +136 -0
  62. data/spec/atom/comment_spec.rb +455 -0
  63. data/spec/atom/feed_spec.rb +684 -0
  64. data/spec/audio_spec.rb +164 -0
  65. data/spec/badge_spec.rb +136 -0
  66. data/spec/binary_spec.rb +218 -0
  67. data/spec/bookmark.rb +150 -0
  68. data/spec/collection_spec.rb +152 -0
  69. data/spec/comment_spec.rb +128 -0
  70. data/spec/crypto_spec.rb +126 -0
  71. data/spec/device_spec.rb +136 -0
  72. data/spec/event_spec.rb +239 -0
  73. data/spec/feed_spec.rb +252 -0
  74. data/spec/file_spec.rb +190 -0
  75. data/spec/group_spec.rb +136 -0
  76. data/spec/helper.rb +10 -0
  77. data/spec/identity_spec.rb +67 -0
  78. data/spec/image_spec.rb +150 -0
  79. data/spec/link_spec.rb +30 -0
  80. data/spec/note_spec.rb +163 -0
  81. data/spec/notification_spec.rb +89 -0
  82. data/spec/person_spec.rb +244 -0
  83. data/spec/place_spec.rb +162 -0
  84. data/spec/product_spec.rb +150 -0
  85. data/spec/question_spec.rb +156 -0
  86. data/spec/review_spec.rb +149 -0
  87. data/spec/service_spec.rb +136 -0
  88. data/spec/video_spec.rb +164 -0
  89. data/test/example_feed.atom +393 -0
  90. data/test/example_feed_empty_author.atom +336 -0
  91. data/test/example_feed_false_connected.atom +359 -0
  92. data/test/example_feed_link_without_href.atom +134 -0
  93. data/test/example_page.html +4 -0
  94. data/test/mime_type_bug_feed.atom +874 -0
  95. metadata +288 -0
@@ -0,0 +1,306 @@
1
+ require 'nelumba/activity'
2
+
3
+ module Nelumba
4
+ require 'atom'
5
+
6
+ # Holds information about the author of the Feed.
7
+ class Person
8
+ require 'date'
9
+
10
+ # Holds the id that represents this contact.
11
+ attr_reader :uid
12
+
13
+ # Holds the nickname of this contact.
14
+ attr_reader :nickname
15
+
16
+ # Holds a hash representing information about the name of this contact.
17
+ #
18
+ # contains one or more of the following:
19
+ # :formatted => The full name of the contact
20
+ # :family_name => The family name. "Last name" in Western contexts.
21
+ # :given_name => The given name. "First name" in Western contexts.
22
+ # :middle_name => The middle name.
23
+ # :honorific_prefix => "Title" in Western contexts. (e.g. "Mr." "Mrs.")
24
+ # :honorific_suffix => "Suffix" in Western contexts. (e.g. "Esq.")
25
+ attr_reader :extended_name
26
+
27
+ # The uri that uniquely identifies the author.
28
+ attr_reader :uri
29
+
30
+ # The email address of the author.
31
+ attr_reader :email
32
+
33
+ # The name of the author
34
+ attr_reader :name
35
+
36
+ # Holds a hash representing the address of the contact.
37
+ #
38
+ # contains one or more of the following:
39
+ # :formatted => A formatted representating of the address. May
40
+ # contain newlines.
41
+ # :street_address => The full street address. May contain newlines.
42
+ # :locality => The city or locality component.
43
+ # :region => The state or region component.
44
+ # :postal_code => The zipcode or postal code component.
45
+ # :country => The country name component.
46
+ attr_reader :address
47
+
48
+ # Holds a hash representing an organization for this contact.
49
+ #
50
+ # contains one or more of the following:
51
+ # :name => The name of the organization (e.g. company, school,
52
+ # etc) This field is required. Will be used for sorting.
53
+ # :department => The department within the organization.
54
+ # :title => The title or role within the organization.
55
+ # :type => The type of organization. Canonical values include
56
+ # "job" or "school"
57
+ # :start_date => A DateTime representing when the contact joined
58
+ # the organization.
59
+ # :end_date => A DateTime representing when the contact left the
60
+ # organization.
61
+ # :location => The physical location of this organization.
62
+ # :description => A free-text description of the role this contact
63
+ # played in this organization.
64
+ attr_reader :organization
65
+
66
+ # Holds a hash representing information about an account held by this
67
+ # contact.
68
+ #
69
+ # contains one or more of the following:
70
+ # :domain => The top-most authoriative domain for this account. (e.g.
71
+ # "twitter.com") This is the primary field. Is required.
72
+ # Used for sorting.
73
+ # :username => An alphanumeric username, typically chosen by the user.
74
+ # :userid => A user id, typically assigned, that uniquely refers to
75
+ # the user.
76
+ attr_reader :account
77
+
78
+ # Holds the gender of this contact.
79
+ attr_reader :gender
80
+
81
+ # Holds the requested pronouns.
82
+ #
83
+ # contains one or more of the following:
84
+ # :plural => Whether or not the actor is considered plural
85
+ # :personal => Personal pronoun (xe)
86
+ # :possessive => Possessive pronoun (her)
87
+ attr_reader :pronoun
88
+
89
+ # Holds a note for this contact.
90
+ attr_reader :note
91
+
92
+ # Holds the display name for this contact.
93
+ attr_reader :display_name
94
+
95
+ # Holds the preferred username of this contact.
96
+ attr_reader :preferred_username
97
+
98
+ # Holds a DateTime that represents when this contact was last modified.
99
+ attr_reader :updated
100
+
101
+ # Holds a DateTime that represents when this contact was originally
102
+ # published.
103
+ attr_reader :published
104
+
105
+ # Holds a DateTime representing this contact's birthday.
106
+ attr_reader :birthday
107
+
108
+ # Holds a DateTime representing a contact's anniversary.
109
+ attr_reader :anniversary
110
+
111
+ # Creates a representating of an author.
112
+ #
113
+ # options:
114
+ # name => The name of the author. Defaults: "anonymous"
115
+ # uid => The identifier that uniquely identifies the
116
+ # contact.
117
+ # nickname => The nickname of the contact.
118
+ # gender => The gender of the contact.
119
+ # note => A note for this contact.
120
+ # display_name => The display name for this contact.
121
+ # preferred_username => The preferred username for this contact.
122
+ # updated => A DateTime representing when this contact was
123
+ # last updated.
124
+ # published => A DateTime representing when this contact was
125
+ # originally created.
126
+ # birthday => A DateTime representing a birthday for this
127
+ # contact.
128
+ # anniversary => A DateTime representing an anniversary for this
129
+ # contact.
130
+ # extended_name => A Hash representing the name of the contact.
131
+ # organization => A Hash representing the organization of which the
132
+ # contact belongs.
133
+ # account => A Hash describing the authorative account for the
134
+ # author.
135
+ # address => A Hash describing the address of the contact.
136
+ # uri => The uri that uniquely identifies this author.
137
+ # email => The email of the author.
138
+ def initialize(options = {})
139
+ init(options)
140
+ end
141
+
142
+ def init(options = {})
143
+ @uri = options[:uri]
144
+ @name = options[:name] || "anonymous"
145
+ @email = options[:email]
146
+
147
+ @uid = options[:uid]
148
+ @name = options[:name]
149
+ @gender = options[:gender]
150
+ @note = options[:note]
151
+ @nickname = options[:nickname]
152
+ @display_name = options[:display_name]
153
+ @preferred_username = options[:preferred_username]
154
+ @updated = options[:updated]
155
+ @published = options[:published]
156
+ @birthday = options[:birthday]
157
+ @anniversary = options[:anniversary]
158
+
159
+ @pronoun = options[:pronoun] || {}
160
+
161
+ @extended_name = options[:extended_name]
162
+ @organization = options[:organization]
163
+ @account = options[:account]
164
+ @address = options[:address]
165
+ end
166
+
167
+ def to_hash
168
+ {
169
+ :uri => self.uri,
170
+ :email => self.email,
171
+ :name => self.name,
172
+
173
+ :uid => self.uid,
174
+ :gender => self.gender,
175
+ :note => self.note,
176
+ :nickname => self.nickname,
177
+ :display_name => self.display_name,
178
+ :preferred_username => self.preferred_username,
179
+ :updated => self.updated,
180
+ :published => self.published,
181
+ :birthday => self.birthday,
182
+ :anniversary => self.anniversary,
183
+
184
+ :pronoun => self.pronoun,
185
+
186
+ :extended_name => self.extended_name,
187
+ :organization => self.organization,
188
+ :account => self.account,
189
+ :address => self.address
190
+ }
191
+ end
192
+
193
+ def to_json_hash
194
+ {
195
+ :uri => self.uri,
196
+ :email => self.email,
197
+ :name => self.name,
198
+ :objectType => "person",
199
+
200
+ :id => self.uid,
201
+ :gender => self.gender,
202
+ :note => self.note,
203
+ :nickname => self.nickname,
204
+ :displayName => self.display_name,
205
+ :preferredUsername => self.preferred_username,
206
+ :updated => self.updated,
207
+ :published => self.published,
208
+ :birthday => self.birthday,
209
+ :anniversary => self.anniversary,
210
+
211
+ :pronoun => self.pronoun,
212
+
213
+ :extendedName => self.extended_name,
214
+ :organization => self.organization,
215
+ :account => self.account,
216
+ :address => self.address
217
+ }
218
+ end
219
+
220
+ # Creates an Activity where this author acts upon the given object.
221
+ def act(action, object)
222
+ type = "person"
223
+ type = object.type if object.is_a? Nelumba::Activity
224
+
225
+ Nelumba::Activity.new :verb => action,
226
+ :actor => self,
227
+ :object => object,
228
+ :type => type
229
+ end
230
+
231
+ # Creates an Activity where this author favorites the given activity.
232
+ def favorite(activity)
233
+ self.act(activity, :favorite)
234
+ end
235
+
236
+ # Creates an Activity where this author unfavorites the given activity.
237
+ def unfavorite(activity)
238
+ self.act(activity, :unfavorite)
239
+ end
240
+
241
+ # Creates an Activity where this author shares the given activity.
242
+ def share(activity)
243
+ self.act(activity, :share)
244
+ end
245
+
246
+ # Creates an Activity where this author unshares the given activity.
247
+ def unshare(activity)
248
+ self.act(activity, :unshare)
249
+ end
250
+
251
+ # Creates an Activity where this author follows the given author.
252
+ def follow(author)
253
+ self.act(author, :follow)
254
+ end
255
+
256
+ # Creates an Activity where this author stops following the given author.
257
+ def unfollow(author)
258
+ self.act(author, :"stop-following")
259
+ end
260
+
261
+ # Determines the displayed name to use to refer to this Person.
262
+ def preferred_display_name
263
+ if self.display_name
264
+ self.display_name
265
+ elsif self.name
266
+ self.name
267
+ elsif self.preferred_username
268
+ self.preferred_username
269
+ elsif self.nickname
270
+ self.nickname
271
+ else
272
+ self.uid
273
+ end
274
+ end
275
+
276
+ # Determines the short name to use to refer to this Person.
277
+ def preferred_short_name
278
+ if self.preferred_username
279
+ self.preferred_username
280
+ elsif self.nickname
281
+ self.nickname
282
+ elsif self.display_name
283
+ self.display_name
284
+ elsif self.name
285
+ self.name
286
+ else
287
+ self.uid
288
+ end
289
+ end
290
+
291
+ # Returns a string containing the JSON representation of this Person.
292
+ def to_json(*args)
293
+ to_json_hash.delete_if{|k,v| v.nil?}.to_json(*args)
294
+ end
295
+
296
+ def to_as1(*args)
297
+ to_json_hash.delete_if{|k,v| v.nil?}.to_json(*args)
298
+ end
299
+
300
+ def to_atom
301
+ require 'nelumba/atom/person'
302
+
303
+ Nelumba::Atom::Person.from_canonical(self).to_xml
304
+ end
305
+ end
306
+ end
@@ -0,0 +1,34 @@
1
+ module Nelumba
2
+ class Place
3
+ include Nelumba::Object
4
+
5
+ attr_reader :position
6
+ attr_reader :address
7
+
8
+ def initialize(options = {}, &blk)
9
+ init(options, &blk)
10
+ end
11
+
12
+ def init(options = {}, &blk)
13
+ super(options, &blk)
14
+
15
+ @position = options[:position]
16
+ @address = options[:address]
17
+ end
18
+
19
+ def to_hash
20
+ {
21
+ :position => @position,
22
+ :address => @address
23
+ }.merge(super)
24
+ end
25
+
26
+ def to_json_hash
27
+ {
28
+ :objectType => "place",
29
+ :position => @position,
30
+ :address => @address
31
+ }.merge(super)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ module Nelumba
2
+ class Product
3
+ include Nelumba::Object
4
+
5
+ attr_reader :full_image
6
+
7
+ def initialize(options = {}, &blk)
8
+ init(options, &blk)
9
+ end
10
+
11
+ def init(options = {}, &blk)
12
+ super(options, &blk)
13
+
14
+ @full_image = options[:full_image]
15
+ end
16
+
17
+ def to_hash
18
+ {
19
+ :full_image => @full_image
20
+ }.merge(super)
21
+ end
22
+
23
+ def to_json_hash
24
+ {
25
+ :objectType => "product",
26
+ :fullImage => @full_image
27
+ }.merge(super)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,44 @@
1
+ module Nelumba
2
+ class Publisher
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ # The url of the feed.
7
+ attr_reader :url
8
+
9
+ # The array of feed urls used to push content. Default: []
10
+ attr_reader :hubs
11
+
12
+ # Creates a representation of a Publisher entity.
13
+ #
14
+ # options:
15
+ # :feed => A feed to use to populate the other fields.
16
+ # :url => The url of the feed that will be published.
17
+ # :hubs => An array of hub urls that are used to handle load
18
+ # balancing pushes of new data. Default: []
19
+ def initialize(options = {}, &blk)
20
+ init(options, &blk)
21
+ end
22
+
23
+ def init(options = {}, &blk)
24
+ if options[:feed]
25
+ @url = options[:feed].url
26
+ @hubs = options[:feed].hubs
27
+ end
28
+
29
+ @url ||= options[:url]
30
+ @hubs ||= options[:hubs] || []
31
+ end
32
+
33
+ # Will ping PuSH hubs so that they know there is new/updated content. The
34
+ # hub should respond by pulling the new data and then sending it to
35
+ # subscribers.
36
+ def ping_hubs
37
+ @hubs.each do |hub_url|
38
+ res = Net::HTTP.post_form(URI.parse(hub_url),
39
+ { 'hub.mode' => 'publish',
40
+ 'hub.url' => @topic_url })
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,30 @@
1
+ module Nelumba
2
+ class Question
3
+ include Nelumba::Object
4
+
5
+ attr_reader :options
6
+
7
+ def initialize(options = {}, &blk)
8
+ init(options, &blk)
9
+ end
10
+
11
+ def init(options = {}, &blk)
12
+ super(options, &blk)
13
+
14
+ @options = options[:options] || []
15
+ end
16
+
17
+ def to_hash
18
+ {
19
+ :options => @options.dup
20
+ }.merge(super)
21
+ end
22
+
23
+ def to_json_hash
24
+ {
25
+ :objectType => "question",
26
+ :options => @options.dup
27
+ }.merge(super)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ module Nelumba
2
+ class Review
3
+ include Nelumba::Object
4
+
5
+ attr_reader :rating
6
+
7
+ def initialize(options = {}, &blk)
8
+ init(options, &blk)
9
+ end
10
+
11
+ def init(options = {}, &blk)
12
+ super options
13
+
14
+ @rating = options[:rating]
15
+ end
16
+
17
+ def to_hash
18
+ {
19
+ :rating => @rating
20
+ }.merge(super)
21
+ end
22
+
23
+ def to_json_hash
24
+ {
25
+ :objectType => "review",
26
+ :rating => @rating
27
+ }.merge(super)
28
+ end
29
+ end
30
+ end