cloudwow-not_relational 0.1.0

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 (78) hide show
  1. data/README.rdoc +7 -0
  2. data/VERSION.yml +4 -0
  3. data/lib/not_relational/acts_as_not_relational_application.rb +11 -0
  4. data/lib/not_relational/and_condition.rb +10 -0
  5. data/lib/not_relational/attribute_range.rb +57 -0
  6. data/lib/not_relational/berkeley_repository.rb +48 -0
  7. data/lib/not_relational/configuration.rb +111 -0
  8. data/lib/not_relational/crypto.rb +58 -0
  9. data/lib/not_relational/domain_model.rb +855 -0
  10. data/lib/not_relational/domain_model_cache_item.rb +14 -0
  11. data/lib/not_relational/equals_condition.rb +18 -0
  12. data/lib/not_relational/geo.rb +188 -0
  13. data/lib/not_relational/index_description.rb +41 -0
  14. data/lib/not_relational/is_null_transform.rb +16 -0
  15. data/lib/not_relational/lazy_loading_text.rb +29 -0
  16. data/lib/not_relational/local_storage.rb +38 -0
  17. data/lib/not_relational/memcache_repository.rb +91 -0
  18. data/lib/not_relational/memory_repository.rb +273 -0
  19. data/lib/not_relational/memory_storage.rb +33 -0
  20. data/lib/not_relational/or_condition.rb +53 -0
  21. data/lib/not_relational/property_description.rb +102 -0
  22. data/lib/not_relational/query_string_auth_generator.rb +166 -0
  23. data/lib/not_relational/reference.rb +28 -0
  24. data/lib/not_relational/repository.rb +419 -0
  25. data/lib/not_relational/repository_factory.rb +67 -0
  26. data/lib/not_relational/repository_interface.rb +48 -0
  27. data/lib/not_relational/s3.rb +581 -0
  28. data/lib/not_relational/sdb_formatter.rb +119 -0
  29. data/lib/not_relational/sdb_monkey_patch.rb +47 -0
  30. data/lib/not_relational/starts_with_condition.rb +21 -0
  31. data/lib/not_relational/storage.rb +223 -0
  32. data/lib/not_relational/tag_cloud.rb +56 -0
  33. data/lib/not_relational/tracker_description.rb +26 -0
  34. data/lib/not_relational/uuid.rb +285 -0
  35. data/lib/not_relational.rb +17 -0
  36. data/test/models/album.rb +206 -0
  37. data/test/models/blurb.rb +65 -0
  38. data/test/models/blurb_wording.rb +18 -0
  39. data/test/models/comment.rb +27 -0
  40. data/test/models/error.rb +14 -0
  41. data/test/models/friend.rb +27 -0
  42. data/test/models/friend_request.rb +34 -0
  43. data/test/models/geo.rb +186 -0
  44. data/test/models/group.rb +283 -0
  45. data/test/models/language.rb +16 -0
  46. data/test/models/media_file.rb +32 -0
  47. data/test/models/media_item.rb +258 -0
  48. data/test/models/message.rb +26 -0
  49. data/test/models/node.rb +282 -0
  50. data/test/models/outgoing_email.rb +26 -0
  51. data/test/models/page_view_detail.rb +15 -0
  52. data/test/models/page_view_summary.rb +15 -0
  53. data/test/models/place.rb +103 -0
  54. data/test/models/rating.rb +21 -0
  55. data/test/models/tag.rb +89 -0
  56. data/test/models/user.rb +289 -0
  57. data/test/models/user_event.rb +67 -0
  58. data/test/models/weblab.rb +17 -0
  59. data/test/unit_tests/album_test.rb +181 -0
  60. data/test/unit_tests/bdb_test.rb +34 -0
  61. data/test/unit_tests/blurb_test.rb +110 -0
  62. data/test/unit_tests/comment_test.rb +42 -0
  63. data/test/unit_tests/composite_key_test.rb +75 -0
  64. data/test/unit_tests/enum_test.rb +32 -0
  65. data/test/unit_tests/group_test.rb +214 -0
  66. data/test/unit_tests/mediaitem_test.rb +412 -0
  67. data/test/unit_tests/memcache_repository_test.rb +40 -0
  68. data/test/unit_tests/memory_repository_test.rb +69 -0
  69. data/test/unit_tests/node_test.rb +490 -0
  70. data/test/unit_tests/place_test.rb +219 -0
  71. data/test/unit_tests/reference_set_test.rb +66 -0
  72. data/test/unit_tests/repository_factory_test.rb +16 -0
  73. data/test/unit_tests/tag_test.rb +86 -0
  74. data/test/unit_tests/user_test.rb +102 -0
  75. data/test/unit_tests/uuid.state +3 -0
  76. data/test/utils/create_sdb_domains.rb +44 -0
  77. data/test/utils/whack_domains.rb +32 -0
  78. metadata +134 -0
@@ -0,0 +1,283 @@
1
+ require 'digest/sha1'
2
+ require "uri"
3
+ require "not_relational/domain_model.rb"
4
+ require "models/tag.rb"
5
+
6
+ class Group < NotRelational::DomainModel
7
+ encrypt_me
8
+ property :id,:string,:is_primary_key=>true
9
+ property :name , :string,:unique=>true
10
+ property :normalized_name , :string,:unique=>true
11
+ property :creator , :string
12
+ property :creation_date , :date
13
+ property :description , :string
14
+ property :is_public , :boolean
15
+ property :short_description , :string
16
+ property :icon_guid , :string
17
+ property :tags , :string
18
+ property :layout , :clob
19
+ property :domain , :string,:unique=>true
20
+
21
+ property :devpay_user_token , :string
22
+ property :devpay_bucket , :string
23
+
24
+
25
+ has_many :GroupInvite
26
+ has_many :GroupMember,:group_id ,:group_members,:order_by => :member_login
27
+ has_many :GroupChannel
28
+ has_many :Album,:group_id,:albums,:order=>:descending,:order_by=>:created_time_utc
29
+ has_many :MediaItem,:group_id,:media_items,:order=>:descending,:order_by=>:created_time
30
+ many_to_many :Node,:GroupChannel,:group_id,:node_id,:channels
31
+
32
+
33
+
34
+
35
+ def Group.create_group(name,short_description,description,tags,is_public,creator_login)
36
+
37
+ group=Group.find_by_normalized_name(name)
38
+ if !group
39
+ group=Group.new
40
+ group.name=name
41
+ group.description=description
42
+ group.short_description=short_description
43
+ group.is_public=is_public
44
+ group.creator=creator_login
45
+ group.creation_date=Time.now.gmtime
46
+ group.tags=tags
47
+ group.save!
48
+
49
+ channel_node=Node.fill_new_node(creator_login,name+" Discussion","")
50
+ channel_node.isChannel=true
51
+ channel_node.publicRead=false
52
+ channel_node.publicWrite=false
53
+ channel_node.save!
54
+
55
+ group_channel=GroupChannel.new
56
+ group_channel.node_id=channel_node.id
57
+ group_channel.group_id=group.id
58
+ group_channel.save
59
+
60
+ group.add_member(creator_login)
61
+ end
62
+ return group
63
+ end
64
+ def add_member(login)
65
+ member=GroupMember.find_by_group_and_login(self.id,login)
66
+ if ! member
67
+ member=GroupMember.new
68
+ member.group_id=self.id
69
+ member.member_login=login
70
+ member.save!
71
+ @accessor_cache.delete(:group_members)
72
+ end
73
+
74
+ return member
75
+ end
76
+ def members
77
+ result=[]
78
+ for member in self.group_members
79
+ member_user=User.find(member.member_login)
80
+ result<<member_user if member_user
81
+ end
82
+ return result;
83
+ end
84
+ def Group.url_from_name(name)
85
+ "/groups/"+URI.escape(name.capitalize, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
86
+ end
87
+ def Group.create_thread_form_url_from_name(name)
88
+ Group.url_from_name(name)+"/forum/create_thread_form"
89
+ end
90
+ def Group.create_thread_url_from_name(name)
91
+ Group.url_from_name(name)+"/forum/create_thread"
92
+ end
93
+ def Group.show_thread_url_from_name(name,thread_id)
94
+ return Group.url_from_name(name)+"/thread/#{thread_id}"
95
+ end
96
+ def Group.domained_groups
97
+ Group.find(:all,:params=>{:domain=>:NOT_NULL})
98
+ end
99
+ def url
100
+ Group.url_from_name(self.name)
101
+ end
102
+ def tag_url(tag_name)
103
+ self.url+"/tag/"+URI.escape(tag_name.downcase, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
104
+ end
105
+ def members_url
106
+ self.url
107
+ end
108
+ def Group.forum_url_from_name(name)
109
+ Group.url_from_name(name)+"/forum"
110
+ end
111
+ def forum_url
112
+ Group.forum_url_from_name(self.name)
113
+ end
114
+ def invite_url
115
+ self.url+"/invite"
116
+ end
117
+ def create_album_url
118
+ Group.create_album_url_from_name(self.name.downcase)
119
+ end
120
+ def Group.create_album_url_from_name(name)
121
+ Group.url_from_name(name)+"/create_album"
122
+ end
123
+
124
+ def create_event_url
125
+ self.url+"/create_event"
126
+ end
127
+ def create_thread_url
128
+ Group.create_thread_url_from_name(self.name.downcase)
129
+ end
130
+ def show_thread_url(thread_id)
131
+ return Group.show_thread_url_from_name(self.name,thread_id)
132
+ end
133
+
134
+ def create_thread_form_url
135
+ Group.create_thread_form_url_from_name(self.name.downcase)
136
+ end
137
+ def join_url
138
+
139
+ self.url+"/join_public"
140
+ end
141
+ def join_with_invitation_url(token,language=nil)
142
+ domain=self.domain || "globalcoordinate.com"
143
+ if language
144
+ domain=language+"."+domain
145
+ end
146
+ return "http://"+domain+self.url+"/join/"+token
147
+ end
148
+ def news_feed_url
149
+ self.url+"/news_stream"
150
+ end
151
+ def members_url
152
+ self.url+"/members"
153
+ end
154
+ def albums_url
155
+ self.url+"/albums"
156
+ end
157
+ def create_invite(email_address)
158
+
159
+ invite=GroupInvite.new
160
+ invite.token="#{NotRelational::UUID.generate.to_s}"
161
+ invite.group_id=self.id
162
+ invite.email_address=email_address
163
+ invite.save!
164
+ return invite
165
+ end
166
+ def tag_cloud
167
+ tag_cloud=TagCloud.new(Tag.find_group_media_tags(self.id ))
168
+
169
+ end
170
+ def channel
171
+ temp=channels
172
+ return nil if temp.length==0
173
+ return temp[0]
174
+ end
175
+ def is_my_thread(thread_node)
176
+ return thread_node.parent_id==channel.id
177
+
178
+
179
+ end
180
+ def icon
181
+ if self.icon_guid
182
+ return Mediaitem.find(:first,:params=>{:guid=>self.icon_guid})
183
+ end
184
+ end
185
+ @cached_events=nil
186
+ def recent_events(how_many=32)
187
+
188
+ UserEvent.find(:all,:limit=>how_many,:order=>:descending,:order_by=>:event_time,:params=>{:group_id=>self.id})
189
+
190
+
191
+ end
192
+ def Group.find_by_normalized_name(value)
193
+ find(:first,:params=>{:normalized_name=>value.capitalize})
194
+
195
+ end
196
+ def Group.find_by_name(value)
197
+ Group.find_by_normalized_name(value)
198
+
199
+ end
200
+ def name=(value)
201
+ self.normalized_name=value
202
+ super(value)
203
+ end
204
+ def normalized_name=(value)
205
+ value=value.capitalize
206
+ super(value)
207
+ end
208
+ def Group.convert_arg_to_group(group_arg)
209
+ return nil unless group_arg
210
+ group=nil
211
+ if group_arg.respond_to?(:name)
212
+ group=group_arg
213
+ else
214
+ group=Group.find_by_normalized_name(group_arg)
215
+ end
216
+ return group
217
+ end
218
+ def is_member?(login)
219
+ member=GroupMember.find_by_group_and_login(self.id,login)
220
+ return member!=nil
221
+
222
+ end
223
+ def create_thread(author,title,content)
224
+ channel=self.channels[0]
225
+
226
+ new_node=Node.fill_new_node(author,title,content)
227
+ new_node.parent_id=channel.id
228
+ new_node.publicRead=false
229
+
230
+ new_node.group_id=self.id
231
+ # new_node.is_private=true
232
+ new_node.save!
233
+ new_node
234
+ end
235
+ def post_to_thread( author_login,thread_id,content)
236
+
237
+
238
+ channel=self.channels[0]
239
+ thread=Node.find(thread_id)
240
+ author=User.find(author_login)
241
+ return if thread.parent_id!=channel.id
242
+ new_node=Node.fill_new_node(author.login,"re: "+thread.latestTitle,content)
243
+ new_node.parent_id=thread.id
244
+ new_node.is_sterile=true;
245
+ new_node.isNews=false
246
+ new_node.publicRead=false
247
+ new_node.group_id=self.id
248
+ new_node.save!
249
+
250
+ thread.last_branch_update_time=new_node.last_branch_update_time
251
+ thread.save!
252
+ channel.last_branch_update_time=new_node.last_branch_update_time
253
+ channel.save!
254
+ end
255
+ end
256
+ class GroupChannel < NotRelational::DomainModel
257
+ property :id,:string,:is_primary_key=>true
258
+ property :group_id,:string
259
+ property :node_id,:string
260
+ belongs_to :Group
261
+ belongs_to :Node
262
+ end
263
+ class GroupMember < NotRelational::DomainModel
264
+ property :id,:string,:is_primary_key=>true
265
+ property :group_id,:string
266
+ property :member_login,:string
267
+ belongs_to :Group
268
+ belongs_to :User,:member_login,:member
269
+ index :group_and_login,[:group_id,:member_login],:unique=>true
270
+ end
271
+ class GroupInvite < NotRelational::DomainModel
272
+ property :id,:string,:is_primary_key=>true
273
+ property :group_id,:string
274
+ property :expiration_time,:date
275
+ property :redeemed_by_login,:string
276
+ property :redeemed_time,:date
277
+ property :outgoing_email_id,:string
278
+ property :token,:string,:unique=>true
279
+ property :email_address,:string
280
+
281
+ belongs_to :Group
282
+ belongs_to :OutgoingEmail,:outgoing_email_id
283
+ end
@@ -0,0 +1,16 @@
1
+ require 'digest/sha1'
2
+ require "uri"
3
+
4
+ require "model/domain_model.rb"
5
+
6
+
7
+ class Language < DomainModel
8
+ property :id,:string,:is_primary_key=>true
9
+ property :name,:string
10
+ property :enabled ,:boolean
11
+
12
+ def Language.enabled_languages
13
+ Language.find(:all,:order_by => 'name',:params=>{:enabled=>true})
14
+
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ require 'digest/sha1'
2
+ require "uri"
3
+
4
+ require "not_relational/domain_model.rb"
5
+ class Mediafile < NotRelational::DomainModel
6
+
7
+ property :id,:string,:is_primary_key=>true
8
+ property :mediaitem_id,:string
9
+ property :mimeType,:string
10
+
11
+ property :width,:unsigned_integer
12
+ property :height,:unsigned_integer
13
+ property :fileSize,:unsigned_integer
14
+ property :bucket,:string
15
+ property :guid,:string,:unique=>true
16
+
17
+ belongs_to :Mediaitem
18
+
19
+
20
+
21
+
22
+ def url
23
+ return "http://s3.amazonaws.com/#{self.bucket}/media/#{self.guid}"
24
+ end
25
+ def view_url
26
+
27
+ return "/media/#{self.mediaitem.guid}/#{width}x#{height}/show.html"
28
+ end
29
+
30
+
31
+
32
+ end
@@ -0,0 +1,258 @@
1
+ require 'digest/sha1'
2
+ require "uri"
3
+
4
+ require "models/tag.rb"
5
+ require "models/comment.rb"
6
+ require "models/rating.rb"
7
+ require "models/album.rb"
8
+ require "models/media_file.rb"
9
+
10
+ class Mediaitem < NotRelational::DomainModel
11
+ extend NotRelational::Geo::Locatable
12
+ include NotRelational::Geo::Locatable
13
+ property :id,:string,:is_primary_key=>true
14
+ property :guid,:string,:unique=>true
15
+ property :group_id , :string
16
+ property :title , :string
17
+ property :user_login , :string
18
+ property :description , :clob
19
+ property :latitude , :float
20
+ property :longitude , :float
21
+
22
+ property :address , :string
23
+ property :bucket , :string
24
+ property :length_in_seconds , :unsigned_integer
25
+ property :HasVideo , :boolean
26
+ property :HasAudio , :boolean
27
+ property :HasImage , :boolean
28
+ property :is_private , :boolean
29
+ property :created_time ,:date
30
+
31
+ has_many :Mediafile,nil,nil,:dependent=>:destroy
32
+ has_many :Tag,nil,nil,:dependent=>:destroy
33
+ has_many :Comment,nil,nil,:dependent=>:destroy
34
+ has_many :Rating,nil,nil,:dependent=>:destroy
35
+ has_many :AlbumMediaItem,nil,nil,:dependent=>:destroy
36
+
37
+ index :hasimage_and_is_private,[:HasImage,:is_private]
38
+ index :hasvideo_and_is_private,[:HasVideo,:is_private]
39
+ index :hasaudio_and_is_private,[:HasAudio,:is_private]
40
+ index :hasaudio_hasvideo_and_is_private,[:HasAudio,:HasVideo,:is_private]
41
+
42
+ many_to_many :Album,:AlbumMediaItem,:mediaitem_id,:album_id,:albums
43
+ belongs_to :Group
44
+ def Mediaitem.recent(how_many=24)
45
+ Mediaitem.find(:all,:order_by => :created_time,:order => :descending,:limit => how_many)
46
+
47
+
48
+ end
49
+ def Mediaitem.recent_video(how_many=24)
50
+
51
+ Mediaitem.find_by_hasvideo_and_is_private(
52
+ true,
53
+ false ,
54
+ :order_by => :created_time,
55
+ :order => :descending,
56
+ :limit => how_many)
57
+
58
+ end
59
+ def Mediaitem.recent_audio(how_many=24)
60
+ Mediaitem.find_by_hasaudio_and_is_private(
61
+ true,
62
+ false ,
63
+ :order_by => :created_time,
64
+ :order => :descending,
65
+ :limit => how_many)
66
+
67
+ end
68
+ #hasimage is unreliable in the db
69
+ def HasImage
70
+ return false if self.HasVideo
71
+ return false if self.HasAudio
72
+ return true
73
+ end
74
+ def Mediaitem.recent_images(how_many=24)
75
+ #images are those that aren't video or audio
76
+ #hasimage flag is not rustworthy
77
+ Mediaitem.find_by_hasaudio_hasvideo_and_is_private(false,false,false ,:order_by => :created_time,:order => :descending,:limit => how_many)
78
+ end
79
+ def create_group_url(group_name)
80
+ return "#{Group.url_from_name(group_name)}/media/#{guid}"
81
+ end
82
+ def relative_url_from_root
83
+ return "media/"+self.guid+"/show.html"
84
+ end
85
+ def url
86
+ return "/media/"+self.guid+"/show.html"
87
+ end
88
+ def post_comment_url
89
+ return "/procyon/post_media_comment_form?mediaitem_id=#{id.to_s}&mediaitem_guid=#{guid}&return_url=#{CGI.escape relative_url_from_root}&mediaitem_thumb_w=#{thumbfile.width}&mediaitem_thumb_h=#{thumbfile.height}&mediaitem_thumb_url=#{thumbfile.url}"
90
+ end
91
+ def thumbfile
92
+ for mediafile in self.mediafiles
93
+ if mediafile.width<=120 and mediafile.height<=120 and (mediafile.width==120 or mediafile.height==120) and mediafile.mimeType.index('image/')==0
94
+ return mediafile
95
+ end
96
+ end
97
+ return tiny_thumbfile
98
+ end
99
+ def tiny_thumbfile
100
+ for mediafile in self.mediafiles
101
+ #not square
102
+ if mediafile.width<=60 and mediafile.height<=60 and (mediafile.height==60 || mediafile.width==60) and mediafile.mimeType.index('image/')==0
103
+ return mediafile
104
+ end
105
+ end
106
+ return nil
107
+ end
108
+ def square_thumbfile
109
+ for mediafile in self.mediafiles
110
+ if mediafile.width==100 and mediafile.height==100 and mediafile.mimeType.index('image/')==0
111
+ return mediafile
112
+ end
113
+ end
114
+ return tiny_thumbfile
115
+ end
116
+ def tiny_square_thumbfile
117
+ for mediafile in self.mediafiles
118
+ if mediafile.width==50 and mediafile.height==50 and mediafile.mimeType.index('image/')==0
119
+ return mediafile
120
+ end
121
+ end
122
+ return tiny_thumbfile
123
+ end
124
+ def big_thumbfile
125
+ for mediafile in self.mediafiles
126
+ if mediafile.width>120 and mediafile.width<=240 and mediafile.height>120 and mediafile.height<=240 and mediafile.mimeType.index('image/')==0
127
+ return mediafile
128
+ end
129
+ end
130
+ return thumbfile
131
+ end
132
+ def file640
133
+ biggest=nil
134
+ for mediafile in self.mediafiles
135
+ if mediafile.width<=640 and mediafile.height<=640 and mediafile.width>1
136
+ if !biggest || mediafile.width>biggest.width
137
+ biggest=mediafile
138
+ end
139
+ end
140
+ end
141
+ if !biggest
142
+ return big_thumbfile
143
+ end
144
+ return biggest
145
+ end
146
+ def fileMaxSize
147
+ result=nil
148
+ for mediafile in self.mediafiles
149
+ if result==nil || mediafile.width>result.width
150
+ result=mediafile
151
+ end
152
+ end
153
+
154
+ return result
155
+ end
156
+ def large_files
157
+ result=[]
158
+ for mediafile in self.mediafiles
159
+ if mediafile.width>240 or mediafile.height>240
160
+ result<<mediafile
161
+ end
162
+ end
163
+ if result.length==0
164
+ result<<big_thumbfile
165
+ end
166
+ return result
167
+ end
168
+ def get_file_by_size_string(size)
169
+ the_mediafile=nil
170
+ for mediafile in self.mediafiles
171
+ if "#{mediafile.width}x#{mediafile.height}"==size
172
+ the_mediafile=mediafile
173
+ end
174
+ end
175
+ return the_mediafile
176
+ end
177
+ def get_tag_cloud
178
+ tag_data=self.tags
179
+ histogram=tag_data.inject(Hash.new(0)){|hash,x| hash[x.tag_name]+=1;hash}
180
+ tag_data=histogram.keys
181
+ tag_data=tag_data.sort_by{|x|-histogram[x]}
182
+ end
183
+
184
+ def kill
185
+ # for media_file in mediafiles
186
+ # media_file.destroy
187
+ # end
188
+ # for album_item in albummediaitems
189
+ # album_item.destroy
190
+ # end
191
+ self.destroy
192
+ end
193
+ def add_rating(rating)
194
+ rating.media_item.id=self.id
195
+ rating.save
196
+ end
197
+
198
+ # Helper method that returns the average rating
199
+ #
200
+ def rating
201
+ average = 0.0
202
+ ratings.each { |r|
203
+ average = average + r.rating
204
+ }
205
+ if ratings.size != 0
206
+ average = average / ratings.size
207
+ end
208
+ average
209
+ end
210
+
211
+ # Check to see if a user already rated this rateable
212
+ def rated_by_user?(user_name)
213
+ rtn = false
214
+ if user_name
215
+ self.ratings.each { |b|
216
+ rtn = true if user_name == b.user_name
217
+ }
218
+ end
219
+ rtn
220
+ end
221
+ def get_rating_by_user_name(user_name)
222
+ rtn = 0
223
+ if user_name
224
+ self.ratings.each { |b|
225
+ rtn = b.rating if user_name == b.user_name
226
+ }
227
+ end
228
+ rtn
229
+ end
230
+ def add_media_comment(user_name,comment)
231
+ newComment=Comment.new
232
+ newComment.mediaitem_id=self.id
233
+ newComment.content=comment
234
+ newComment.user_name=user_name
235
+ newComment.posted_time=Time.new.gmtime
236
+ newComment.save
237
+ end
238
+ def Mediaitem.add_media_comment(user_name,mediaitem_id,title,comment)
239
+
240
+ mediaitem=Mediaitem.find(mediaitem_id)
241
+ if mediaitem
242
+
243
+ mediaitem.add_media_comment(user_name,comment)
244
+
245
+
246
+ end
247
+ end
248
+
249
+ def Mediaitem.convert_arg_to_mediaitem(mediaitem_arg)
250
+ item=nil
251
+ if mediaitem_arg.respond_to?(:HasImage)
252
+ item=mediaitem_arg
253
+ else
254
+ item=Mediaitem.find_by_guid(mediaitem_arg)
255
+ end
256
+ return item
257
+ end
258
+ end
@@ -0,0 +1,26 @@
1
+ require "uri"
2
+
3
+ require "not_relational/domain_model.rb"
4
+ class Message < NotRelational::DomainModel
5
+
6
+ property :id,:string,:is_primary_key=>true
7
+ property :title , :string
8
+ property :content , :clob
9
+ property :created_time_utc , :date
10
+ property :from_user_name , :string
11
+ property :to_user_name , :string
12
+
13
+
14
+ belongs_to :User,:from_user_name,:sender
15
+ belongs_to :User,:to_user_name,:recipient
16
+ def url
17
+ return "/messages/#{self.id}"
18
+ end
19
+ def Message.recent(how_many=24)
20
+ Message.find(:all,:limit=>how_many,:order_by =>:created_time_utc, :order=>:descending)
21
+ end
22
+
23
+ def Message.inbox(login,how_many=32)
24
+ Message.find(:all,:limit=>how_many,:order_by =>:created_time_utc, :order=>:descending,:params=>{:to_user_name=>login})
25
+ end
26
+ end