nelumba 0.0.13

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 (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