mailboxer 0.0.15 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -10,3 +10,4 @@ Gemfile.lock
10
10
  .project
11
11
  .document
12
12
  .settings/
13
+ rdoc/
data/Rakefile CHANGED
@@ -1,53 +1,27 @@
1
1
  require 'rubygems'
2
- require 'bundler'
3
2
  begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
3
+ require 'bundler/setup'
4
+ require 'bundler'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
9
7
  end
10
8
  require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "mailboxer"
16
- gem.homepage = "http://github.com/roendal/mailboxer"
17
- gem.license = "MIT"
18
- gem.summary = %Q{Private messaging system for rails apps.}
19
- gem.description = %Q{TODO: longer description of your gem}
20
- gem.email = "ecasanovac@gmail.com"
21
- gem.authors = ["Eduardo Casanova Cuesta"]
22
- # Include your dependencies below. Runtime dependencies are required when using your gem,
23
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
- # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
- # gem.add_development_dependency 'rspec', '> 1.2.3'
26
- gem.add_development_dependency('rspec-rails', '~> 2.4.1')
27
- gem.add_development_dependency('factory_girl', '~> 1.3.2')
28
- gem.add_development_dependency('forgery', '~> 0.3.6')
29
- end
30
- Jeweler::RubygemsDotOrgTasks.new
9
+ require 'rake/rdoctask'
31
10
 
32
11
  require 'rspec/core'
33
12
  require 'rspec/core/rake_task'
34
- RSpec::Core::RakeTask.new(:spec) do |spec|
35
- spec.pattern = FileList['spec/**/*_spec.rb']
36
- end
37
13
 
38
- RSpec::Core::RakeTask.new(:rcov) do |spec|
39
- spec.pattern = 'spec/**/*_spec.rb'
40
- spec.rcov = true
41
- end
14
+ RSpec::Core::RakeTask.new(:spec)
42
15
 
43
16
  task :default => :spec
44
17
 
45
- require 'rake/rdoctask'
46
18
  Rake::RDocTask.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
-
49
19
  rdoc.rdoc_dir = 'rdoc'
50
- rdoc.title = "mailboxer #{version}"
51
- rdoc.rdoc_files.include('README*')
52
- rdoc.rdoc_files.include('lib/**/*.rb')
20
+ rdoc.title = "Mailboxer"
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README.rdoc')
23
+ rdoc.rdoc_files.include('lib/**/*.rb', 'app/**/*.rb')
53
24
  end
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
@@ -1,5 +1,4 @@
1
1
  class Conversation < ActiveRecord::Base
2
- attr_reader :originator, :original_message, :last_sender, :last_message
3
2
  has_many :messages
4
3
  has_many :receipts, :through => :messages
5
4
 
@@ -7,7 +6,6 @@ class Conversation < ActiveRecord::Base
7
6
 
8
7
  before_validation :clean
9
8
 
10
- # before_create :clean
11
9
  scope :participant, lambda {|participant|
12
10
  joins(:receipts).select('DISTINCT conversations.*').where('notifications.type'=> Message.to_s,'receipts.receiver_id' => participant.id,'receipts.receiver_type' => participant.class.to_s).order("conversations.updated_at DESC")
13
11
  }
@@ -23,32 +21,32 @@ class Conversation < ActiveRecord::Base
23
21
  scope :unread, lambda {|participant|
24
22
  joins(:receipts).select('DISTINCT conversations.*').where('notifications.type'=> Message.to_s,'receipts.receiver_id' => participant.id,'receipts.receiver_type' => participant.class.to_s,'receipts.read' => false).order("conversations.updated_at DESC")
25
23
  }
26
- class << self
27
- def total
28
- count('DISTINCT conversations.id')
29
- end
30
- end
31
24
 
25
+ #Mark the conversation as read for one of the participants
32
26
  def mark_as_read(participant)
33
27
  return if participant.nil?
34
28
  return self.receipts_for(participant).mark_as_read
35
29
  end
36
30
 
31
+ #Mark the conversation as unread for one of the participants
37
32
  def mark_as_unread(participant)
38
33
  return if participant.nil?
39
34
  return self.receipts_for(participant).mark_as_unread
40
35
  end
41
36
 
37
+ #Move the conversation to the trash for one of the participants
42
38
  def move_to_trash(participant)
43
39
  return if participant.nil?
44
40
  return self.receipts_for(participant).move_to_trash
45
41
  end
46
42
 
43
+ #Takes the conversation out of the trash for one of the participants
47
44
  def untrash(participant)
48
45
  return if participant.nil?
49
46
  return self.receipts_for(participant).untrash
50
47
  end
51
48
 
49
+ #Returns an array of participants
52
50
  def recipients
53
51
  if self.last_message
54
52
  recps = self.last_message.recipients
@@ -57,71 +55,75 @@ class Conversation < ActiveRecord::Base
57
55
  end
58
56
  return []
59
57
  end
58
+
59
+ #Returns an array of participants
60
+ def participants
61
+ return recipients
62
+ end
60
63
 
61
- #originator of the conversation.
64
+ #Originator of the conversation.
62
65
  def originator
63
66
  @orignator = self.original_message.sender if @originator.nil?
64
67
  return @orignator
65
68
  end
66
69
 
67
- #first message of the conversation.
70
+ #First message of the conversation.
68
71
  def original_message
69
72
  @original_message = self.messages.find(:first, :order => 'created_at') if @original_message.nil?
70
73
  return @original_message
71
74
  end
72
75
 
73
- #sender of the last message.
76
+ #Sender of the last message.
74
77
  def last_sender
75
78
  @last_sender = self.last_message.sender if @last_sender.nil?
76
79
  return @last_sender
77
80
  end
78
81
 
79
- #last message in the conversation.
82
+ #Last message in the conversation.
80
83
  def last_message
81
84
  @last_message = self.messages.find(:first, :order => 'created_at DESC') if @last_message.nil?
82
85
  return @last_message
83
86
  end
84
87
 
88
+ #Returns the receipts of the conversation for one participants
85
89
  def receipts_for(participant)
86
90
  return Receipt.conversation(self).receiver(participant)
87
91
  end
88
92
 
93
+ #Returns the number of messages of the conversation
89
94
  def count_messages
90
95
  return Message.conversation(self).count
91
96
  end
92
97
 
98
+ #Returns true if the messageable is a participant of the conversation
93
99
  def is_participant?(participant)
94
100
  return false if participant.nil?
95
101
  return self.receipts_for(participant).count != 0
96
102
  end
97
103
 
104
+ #Returns true if the participant has at least one trashed message of the conversation
98
105
  def is_trashed?(participant)
99
106
  return false if participant.nil?
100
107
  return self.receipts_for(participant).trash.count!=0
101
108
  end
102
109
 
110
+ #Returns true if the participant has trashed all the messages of the conversation
103
111
  def is_completely_trashed?(participant)
104
112
  return false if participant.nil?
105
113
  return self.receipts_for(participant).trash.count==self.receipts(participant).count
106
114
  end
107
115
 
116
+ #Returns true if the participant has at least one unread message of the conversation
108
117
  def is_unread?(participant)
109
118
  return false if participant.nil?
110
119
  return self.receipts_for(participant).unread.count!=0
111
120
  end
112
- # protected
113
- # #[empty method]
114
- # #
115
- # #this gets called before_create. Implement this if you wish to clean out illegal content such as scripts or anything that will break layout. This is left empty because what is considered illegal content varies.
116
- # def clean
117
- # return if subject.nil?
118
- # #strip all illegal content here. (scripts, shit that will break layout, etc.)
119
- # end
120
121
 
121
122
  protected
122
123
 
123
124
  include ActionView::Helpers::SanitizeHelper
124
125
 
126
+ #Use the default sanitize to clean the conversation subject
125
127
  def clean
126
128
  self.subject = sanitize self.subject
127
129
  end
@@ -1,69 +1,114 @@
1
1
  class Mailbox
2
- attr_accessor :type
3
- attr_reader :messageable
4
- def initialize(recipient, box = :all)
5
- @messageable = recipient
6
- end
7
-
8
- def notifications(options = {})
9
- return Receipt.where(options).receiver(@messageable).notifications
10
- end
2
+ attr_accessor :type
3
+ attr_reader :messageable
4
+ #Initializer method
5
+ def initialize(messageable)
6
+ @messageable = messageable
7
+ end
11
8
 
12
- def conversations(options = {})
13
- conv = Conversation.participant(@messageable)
9
+ #Returns the notifications for the messageable
10
+ def notifications(options = {})
11
+ return Notification.receiver(@messageable)
12
+ end
14
13
 
15
- if options[:mailbox_type].present?
16
- case options[:mailbox_type]
17
- when 'inbox'
18
- conv = Conversation.inbox(@messageable)
19
- when 'sentbox'
20
- conv = Conversation.sentbox(@messageable)
21
- when 'trash'
22
- conv = Conversation.trash(@messageable)
23
- end
24
- end
14
+ #Returns the conversations for the messageable
15
+ #
16
+ #Options
17
+ #
18
+ #* :mailbox_type
19
+ # * "inbox"
20
+ # * "sentbox"
21
+ # * "trash"
22
+ #
23
+ #* :read=false
24
+ #* :unread=true
25
+ #
26
+ def conversations(options = {})
27
+ conv = Conversation.participant(@messageable)
25
28
 
26
- if (options[:read].present? and options[:read]==false) or (options[:unread].present? and options[:unread]==true)
27
- conv = conv.unread(@messageable)
28
- end
29
-
30
- return conv.uniq
31
- end
29
+ if options[:mailbox_type].present?
30
+ case options[:mailbox_type]
31
+ when 'inbox'
32
+ conv = Conversation.inbox(@messageable)
33
+ when 'sentbox'
34
+ conv = Conversation.sentbox(@messageable)
35
+ when 'trash'
36
+ conv = Conversation.trash(@messageable)
37
+ end
38
+ end
32
39
 
33
- def inbox(options={})
34
- options = options.merge(:mailbox_type => 'inbox')
35
- return self.conversations(options)
36
- end
40
+ if (options[:read].present? and options[:read]==false) or (options[:unread].present? and options[:unread]==true)
41
+ conv = conv.unread(@messageable)
42
+ end
37
43
 
38
- def sentbox(options={})
39
- options = options.merge(:mailbox_type => 'sentbox')
40
- return self.conversations(options)
41
- end
44
+ return conv.uniq
45
+ end
42
46
 
43
- def trash(options={})
44
- options = options.merge(:mailbox_type => 'trash')
45
- return self.conversations(options)
46
- end
47
+ #Returns the conversations in the inbox of messageable
48
+ #
49
+ #Same as conversations({:mailbox_type => 'inbox'})
50
+ def inbox(options={})
51
+ options = options.merge(:mailbox_type => 'inbox')
52
+ return self.conversations(options)
53
+ end
47
54
 
48
- def receipts(options = {})
49
- return Receipt.where(options).receiver(@messageable)
50
- end
55
+ #Returns the conversations in the sentbox of messageable
56
+ #
57
+ #Same as conversations({:mailbox_type => 'sentbox'})
58
+ def sentbox(options={})
59
+ options = options.merge(:mailbox_type => 'sentbox')
60
+ return self.conversations(options)
61
+ end
51
62
 
52
- def empty_trash(options = {})
53
- #TODO
54
- return false
55
- end
63
+ #Returns the conversations in the trash of messageable
64
+ #
65
+ #Same as conversations({:mailbox_type => 'trash'})
66
+ def trash(options={})
67
+ options = options.merge(:mailbox_type => 'trash')
68
+ return self.conversations(options)
69
+ end
56
70
 
57
- def has_conversation?(conversation)
58
- return conversation.is_participant?(@messageable)
59
- end
71
+ #Returns all the receipts of messageable, from Messages and Notifications
72
+ def receipts(options = {})
73
+ return Receipt.where(options).receiver(@messageable)
74
+ end
60
75
 
61
- def is_trashed?(conversation)
62
- return conversation.is_trashed?(@messageable)
63
- end
76
+ #Deletes all the messages in the trash of messageable. NOT IMPLEMENTED.
77
+ def empty_trash(options = {})
78
+ #TODO
79
+ return false
80
+ end
64
81
 
65
- def is_completely_trashed?(conversation)
66
- return conversation.is_completely_trashed?(@messageable)
67
- end
82
+ #Returns if messageable is a participant of conversation
83
+ def has_conversation?(conversation)
84
+ return conversation.is_participant?(@messageable)
85
+ end
86
+
87
+ #Returns true if messageable has at least one trashed message of the conversation
88
+ def is_trashed?(conversation)
89
+ return conversation.is_trashed?(@messageable)
90
+ end
91
+
92
+ #Returns true if messageable has trashed all the messages of the conversation
93
+ def is_completely_trashed?(conversation)
94
+ return conversation.is_completely_trashed?(@messageable)
95
+ end
96
+
97
+ #Returns the receipts of object for messageable
98
+ #
99
+ #Object can be:
100
+ #* A Message
101
+ #* A Notification
102
+ #* A Conversation
103
+ def receipts_for(object)
104
+ case object
105
+ when Message,Notification
106
+ return [object.receipt_for(@messageable)]
107
+ when Conversation
108
+ return object.receipts_for(@messageable)
109
+ else
110
+ return Array.new
111
+ end
112
+ end
68
113
 
69
114
  end
@@ -8,12 +8,16 @@ class Message < Notification
8
8
  scope :conversation, lambda { |conversation|
9
9
  where(:conversation_id => conversation.id)
10
10
  }
11
+
11
12
  class << self
13
+ #Sets the on deliver callback method.
12
14
  def on_deliver(callback_method)
13
15
  self.on_deliver_callback = callback_method
14
16
  end
15
17
  end
16
-
18
+
19
+ #Delivers a Message. USE NOT RECOMENDED.
20
+ #Use Mailboxer::Models::Message.send_message instead.
17
21
  def deliver(reply = false, should_clean = true)
18
22
  self.clean if should_clean
19
23
  temp_receipts = Array.new
@@ -45,6 +49,4 @@ class Message < Notification
45
49
  end
46
50
  return sender_receipt
47
51
  end
48
-
49
-
50
52
  end
@@ -5,7 +5,12 @@ class Notification < ActiveRecord::Base
5
5
  validates_presence_of :subject, :body
6
6
  has_many :receipts
7
7
 
8
+ scope :receiver, lambda { |receiver|
9
+ joins(:receipts).where('receipts.receiver_id' => receiver.id,'receipts.receiver_type' => receiver.class.to_s)
10
+ }
11
+
8
12
  class << self
13
+ #Sends a Notification to all the recipients
9
14
  def notify_all(recipients,subject,body)
10
15
  notification = Notification.new({:body => body, :subject => subject})
11
16
  notification.recipients = recipients.is_a?(Array) ? recipients : [recipients]
@@ -14,6 +19,8 @@ class Notification < ActiveRecord::Base
14
19
  end
15
20
  end
16
21
 
22
+ #Delivers a Notification. USE NOT RECOMENDED.
23
+ #Use Mailboxer::Models::Message.notify and Notification.notify_all instead.
17
24
  def deliver(should_clean = true)
18
25
  self.clean if should_clean
19
26
  temp_receipts = Array.new
@@ -32,7 +39,8 @@ class Notification < ActiveRecord::Base
32
39
  end
33
40
  return temp_receipts
34
41
  end
35
-
42
+
43
+ #Returns the recipients of the Notification
36
44
  def recipients
37
45
  if @recipients.blank?
38
46
  recipients_array = Array.new
@@ -44,10 +52,12 @@ class Notification < ActiveRecord::Base
44
52
  return @recipients
45
53
  end
46
54
 
55
+ #Returns the receipt for the participant
47
56
  def receipt_for(participant)
48
57
  return Receipt.notification(self).receiver(participant)
49
58
  end
50
59
 
60
+ #Returns if the participant have read the Notification
51
61
  def is_unread?(participant)
52
62
  return false if participant.nil?
53
63
  return self.receipt_for(participant).unread.count!=0
@@ -55,6 +65,7 @@ class Notification < ActiveRecord::Base
55
65
 
56
66
  include ActionView::Helpers::SanitizeHelper
57
67
 
68
+ #Sanitizes the body and subject
58
69
  def clean
59
70
  unless self.subject.nil?
60
71
  self.subject = sanitize self.subject
@@ -10,8 +10,8 @@ class Receipt < ActiveRecord::Base
10
10
  }
11
11
  #Notifications Scope checks type to be nil, not Notification because of STI behaviour
12
12
  #with the primary class (no type is saved)
13
- scope :notifications, joins(:notification).where('notifications.type' => nil)
14
- scope :messages, joins(:notification).where('notifications.type' => Message.to_s)
13
+ scope :notifications_receipts, joins(:notification).where('notifications.type' => nil)
14
+ scope :messages_receipts, joins(:notification).where('notifications.type' => Message.to_s)
15
15
  scope :notification, lambda { |notification|
16
16
  where(:notification_id => notification.id)
17
17
  }
@@ -27,66 +27,82 @@ class Receipt < ActiveRecord::Base
27
27
 
28
28
  after_validation :remove_duplicate_errors
29
29
  class << self
30
+
31
+ #Marks all the receipts from the relation as read
30
32
  def mark_as_read(options={})
31
33
  where(options).update_all(:read => true)
32
34
  end
33
35
 
36
+ #Marks all the receipts from the relation as unread
34
37
  def mark_as_unread(options={})
35
38
  where(options).update_all(:read => false)
36
39
  end
37
40
 
41
+ #Marks all the receipts from the relation as trashed
38
42
  def move_to_trash(options={})
39
43
  where(options).update_all(:trashed => true)
40
44
  end
41
45
 
46
+ #Marks all the receipts from the relation as not trashed
42
47
  def untrash(options={})
43
48
  where(options).update_all(:trashed => false)
44
49
  end
45
50
 
51
+ #Moves all the receipts from the relation to inbox
46
52
  def move_to_inbox(options={})
47
53
  where(options).update_all(:mailbox_type => :inbox, :trashed => false)
48
54
  end
49
55
 
56
+ #Moves all the receipts from the relation to sentbox
50
57
  def move_to_sentbox(options={})
51
58
  where(options).update_all(:mailbox_type => :sentbox, :trashed => false)
52
59
  end
53
60
  end
54
61
 
62
+ #Marks the receipt as read
55
63
  def mark_as_read
56
64
  update_attributes(:read => true)
57
65
  end
58
66
 
67
+ #Marks the receipt as unread
59
68
  def mark_as_unread
60
69
  update_attributes(:read => false)
61
70
  end
62
71
 
72
+ #Marks the receipt as trashed
63
73
  def move_to_trash
64
74
  update_attributes(:trashed => true)
65
75
  end
66
76
 
77
+ #Marks the receipt as not trashed
67
78
  def untrash
68
79
  update_attributes(:trashed => false)
69
80
  end
70
81
 
82
+ #Moves the receipt to inbox
71
83
  def move_to_inbox
72
84
  update_attributes(:mailbox_type => :inbox, :trashed => false)
73
85
  end
74
86
 
87
+ #Moves the receipt to sentbox
75
88
  def move_to_sentbox
76
89
  update_attributes(:mailbox_type => :sentbox, :trashed => false)
77
90
  end
78
91
 
92
+ #Returns the conversation associated to the receipt if the notification is a Message
79
93
  def conversation
80
- return nil if notification.class == Notification
81
- return notification.conversation if notification.class == Message
94
+ return message.conversation if message.is_a? Message
95
+ return nil
82
96
  end
83
97
 
84
98
  protected
85
99
 
100
+ #Removes the duplicate error about not present subject from Conversation if it has been already
101
+ #raised by Message
86
102
  def remove_duplicate_errors
87
- if self.errors["message.conversation.subject"].present? and self.errors["message.subject"].present?
88
- self.errors["message.conversation.subject"].each do |msg|
89
- self.errors["message.conversation.subject"].delete(msg)
103
+ if self.errors["notification.conversation.subject"].present? and self.errors["notification.subject"].present?
104
+ self.errors["notification.conversation.subject"].each do |msg|
105
+ self.errors["notification.conversation.subject"].delete(msg)
90
106
  end
91
107
  end
92
108
  end
@@ -1,102 +1,127 @@
1
1
  module Mailboxer
2
- module Models
3
- module Messageable
4
- def self.included(mod)
5
- mod.extend(ClassMethods)
6
- end
2
+ module Models
3
+ module Messageable
4
+ def self.included(mod)
5
+ mod.extend(ClassMethods)
6
+ end
7
7
 
8
- module ClassMethods
9
- def acts_as_messageable
10
- has_many :messages
11
- has_many :receipts, :order => 'created_at DESC', :dependent => :delete_all
8
+ module ClassMethods
9
+ #Converts the model into messageable allowing it to interchange messages and
10
+ #receive notifications
11
+ def acts_as_messageable
12
+ has_many :messages
13
+ has_many :receipts, :order => 'created_at DESC', :dependent => :delete_all
12
14
 
13
- include Mailboxer::Models::Messageable::InstanceMethods
14
- end
15
- end
15
+ include Mailboxer::Models::Messageable::InstanceMethods
16
+ end
17
+ end
16
18
 
17
- module InstanceMethods
18
-
19
- ################################### MAILBOXES
20
-
21
- def mailbox
22
- @mailbox = Mailbox.new(self) if @mailbox.nil?
23
- @mailbox.type = :all
24
- return @mailbox
25
- end
26
-
27
- ################################### NOTIFICATIONS
28
-
29
- def notify(subject,body)
19
+ module InstanceMethods
20
+ #Gets the mailbox of the messageable
21
+ def mailbox
22
+ @mailbox = Mailbox.new(self) if @mailbox.nil?
23
+ @mailbox.type = :all
24
+ return @mailbox
25
+ end
26
+
27
+ #Sends a notification to the messageable
28
+ def notify(subject,body)
30
29
  notification = Notification.new({:body => body, :subject => subject})
31
30
  notification.recipients = [self]
32
- return notification.deliver
33
- end
34
-
35
- ################################### MESSAGES
31
+ return notification.deliver
32
+ end
36
33
 
37
- def send_message(recipients, msg_body, subject)
38
- convo = Conversation.new({:subject => subject})
39
- message = Message.new({:sender => self, :conversation => convo, :body => msg_body, :subject => subject})
40
- message.recipients = recipients.is_a?(Array) ? recipients : [recipients]
41
- message.recipients = message.recipients.uniq
42
- return message.deliver
43
- end
34
+ #Sends a messages, starting a new conversation, with the messageable
35
+ #as originator
36
+ def send_message(recipients, msg_body, subject)
37
+ convo = Conversation.new({:subject => subject})
38
+ message = Message.new({:sender => self, :conversation => convo, :body => msg_body, :subject => subject})
39
+ message.recipients = recipients.is_a?(Array) ? recipients : [recipients]
40
+ message.recipients = message.recipients.uniq
41
+ return message.deliver
42
+ end
44
43
 
45
- def reply(conversation, recipients, reply_body, subject = nil)
46
- subject = subject || "RE: #{conversation.subject}"
47
- response = Message.new({:sender => self, :conversation => conversation, :body => reply_body, :subject => subject})
48
- response.recipients = recipients.is_a?(Array) ? recipients : [recipients]
49
- response.recipients = response.recipients.uniq
50
- response.recipients.delete(self)
51
- return response.deliver(true)
52
- end
44
+ #Basic reply method. USE NOT RECOMENDED.
45
+ #Use reply_to_sender, reply_to_all and reply_to_conversation instead.
46
+ def reply(conversation, recipients, reply_body, subject = nil)
47
+ subject = subject || "RE: #{conversation.subject}"
48
+ response = Message.new({:sender => self, :conversation => conversation, :body => reply_body, :subject => subject})
49
+ response.recipients = recipients.is_a?(Array) ? recipients : [recipients]
50
+ response.recipients = response.recipients.uniq
51
+ response.recipients.delete(self)
52
+ return response.deliver(true)
53
+ end
53
54
 
54
- def reply_to_sender(receipt, reply_body, subject = nil)
55
- return reply(receipt.conversation, receipt.notification.sender, reply_body, subject)
56
- end
55
+ #Replies to the sender of the message in the conversation
56
+ def reply_to_sender(receipt, reply_body, subject = nil)
57
+ return reply(receipt.conversation, receipt.message.sender, reply_body, subject)
58
+ end
57
59
 
58
- def reply_to_all(receipt, reply_body, subject = nil)
59
- return reply(receipt.conversation, receipt.notification.recipients, reply_body, subject)
60
- end
60
+ #Replies to all the recipients of the message in the conversation
61
+ def reply_to_all(receipt, reply_body, subject = nil)
62
+ return reply(receipt.conversation, receipt.message.recipients, reply_body, subject)
63
+ end
61
64
 
62
- def reply_to_conversation(conversation, reply_body, subject = nil)
63
- #move conversation to inbox if it is currently in the trash - doesnt make much sense replying to a trashed convo.
64
- if(mailbox.is_trashed?(conversation))
65
- mailbox.receipts.conversation(conversation).untrash
66
- end
67
- #remove self from recipients unless you are the originator of the convo
68
- recipients = conversation.last_message.recipients
69
- if(conversation.originator != self)
70
- recipients.delete(self)
71
- if(!recipients.include?(conversation.originator))
72
- recipients << conversation.originator
73
- end
74
- end
75
- return reply(conversation,recipients, reply_body, subject)
76
- end
65
+ #Replies to all the recipients of the last message in the conversation and untrash any trashed message by messageable
66
+ #if should_untrash is set to true (this is so by default)
67
+ def reply_to_conversation(conversation, reply_body, subject = nil, should_untrash = true)
68
+ #move conversation to inbox if it is currently in the trash and should_untrash parameter is true.
69
+ if should_untrash && mailbox.is_trashed?(conversation)
70
+ mailbox.receipts_for(conversation).untrash
71
+ end
72
+ return reply(conversation, conversation.last_message.recipients, reply_body, subject)
73
+ end
77
74
 
78
- def read_message(obj)
79
- if obj.class.to_s.eql? 'Receipt'
80
- return obj.mark_as_read if obj.receiver == self
81
- elsif obj.class.to_s.eql? 'Message'
82
- receipts = obj.receipts.receiver(self)
83
- return receipts.mark_as_read
84
- end
85
- return nil
86
- end
75
+ #Mark the object as read for messageable.
76
+ #
77
+ #Object can be:
78
+ #* A Receipt
79
+ #* A Message
80
+ #* A Notification
81
+ #* A Conversation
82
+ #* An array with any of them
83
+ def read(obj)
84
+ case obj
85
+ when Receipt
86
+ return obj.mark_as_read if obj.receiver == self
87
+ when Message, Notification
88
+ receipt = obj.receipt_for(self)
89
+ return receipt.mark_as_read
90
+ when Conversation
91
+ receipts = obj.receipts_for(self)
92
+ return receipts.mark_as_read
93
+ when Array
94
+ obj.map{ |sub_obj| read(sub_obj) }
95
+ else
96
+ return nil
97
+ end
98
+ end
87
99
 
88
- def unread_message(obj)
89
- if obj.class.to_s.eql? 'Receipt'
90
- return obj.mark_as_unread if obj.receiver == self
91
- elsif obj.class.to_s.eql? 'Message'
92
- receipts = obj.receipts.receiver(self)
93
- return receipts.mark_as_unread
94
- end
95
- return nil
96
- end
97
-
98
-
99
- end
100
- end
101
- end
100
+ #Mark the object as unread for messageable.
101
+ #
102
+ #Object can be:
103
+ #* A Receipt
104
+ #* A Message
105
+ #* A Notification
106
+ #* A Conversation
107
+ #* An array with any of them
108
+ def unread(obj)
109
+ case obj
110
+ when Receipt
111
+ return obj.mark_as_unread if obj.receiver == self
112
+ when Message, Notification
113
+ receipt = obj.receipt_for(self)
114
+ return receipt.mark_as_unread
115
+ when Conversation
116
+ receipts = obj.receipts_for(self)
117
+ return receipts.mark_as_unread
118
+ when Array
119
+ obj.map{ |sub_obj| unread(sub_obj) }
120
+ else
121
+ return nil
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
102
127
  end
data/mailboxer.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "mailboxer"
3
- s.version = "0.0.15"
3
+ s.version = "0.0.16"
4
4
  s.authors = ["Eduardo Casanova Cuesta"]
5
5
  s.summary = "Messaging system for rails apps."
6
6
  s.description = "A Rails engine that allows any model to act as messageable, permitting it interchange messages with any other messageable model." +
@@ -32,30 +32,30 @@ describe "Mailboxer::Models::Messageable through User" do
32
32
  it "should be able to unread an owned mail (mark as unread)" do
33
33
  @receipt = @entity1.send_message(@entity2,"Body","Subject")
34
34
  @receipt.read.should==true
35
- @entity1.unread_message(@receipt)
35
+ @entity1.unread(@receipt)
36
36
  @receipt.read.should==false
37
37
  end
38
38
 
39
39
  it "should be able to read an owned mail (mark as read)" do
40
40
  @receipt = @entity1.send_message(@entity2,"Body","Subject")
41
41
  @receipt.read.should==true
42
- @entity1.unread_message(@receipt)
43
- @entity1.read_message(@receipt)
42
+ @entity1.unread(@receipt)
43
+ @entity1.read(@receipt)
44
44
  @receipt.read.should==true
45
45
  end
46
46
 
47
47
  it "should be able to unread anot owned mail (mark as unread)" do
48
48
  @receipt = @entity1.send_message(@entity2,"Body","Subject")
49
49
  @receipt.read.should==true
50
- @entity2.unread_message(@receipt) #Should not change
50
+ @entity2.unread(@receipt) #Should not change
51
51
  @receipt.read.should==true
52
52
  end
53
53
 
54
54
  it "should be able to read a not owned mail (mark as read)" do
55
55
  @receipt = @entity1.send_message(@entity2,"Body","Subject")
56
56
  @receipt.read.should==true
57
- @entity1.unread_message(@receipt) #From read to unread
58
- @entity2.read_message(@receipt) #Should not change
57
+ @entity1.unread(@receipt) #From read to unread
58
+ @entity2.read(@receipt) #Should not change
59
59
  @receipt.read.should==false
60
60
  end
61
61
 
@@ -20,8 +20,7 @@ describe Message do
20
20
 
21
21
  #Check getting NOTIFICATION receipts only
22
22
  @entity1.mailbox.notifications.size.should==1
23
- receipt = @entity1.mailbox.notifications.first
24
- notification = receipt.notification
23
+ notification = @entity1.mailbox.notifications.first
25
24
  notification.subject.should=="Subject"
26
25
  notification.body.should=="Body"
27
26
  end
@@ -48,18 +47,15 @@ describe Message do
48
47
 
49
48
  #Check getting NOTIFICATION receipts only
50
49
  @entity1.mailbox.notifications.size.should==1
51
- receipt = @entity1.mailbox.notifications.first
52
- notification = receipt.notification
50
+ notification = @entity1.mailbox.notifications.first
53
51
  notification.subject.should=="Subject"
54
52
  notification.body.should=="Body"
55
53
  @entity2.mailbox.notifications.size.should==1
56
- receipt = @entity2.mailbox.notifications.first
57
- notification = receipt.notification
54
+ notification = @entity2.mailbox.notifications.first
58
55
  notification.subject.should=="Subject"
59
56
  notification.body.should=="Body"
60
57
  @entity3.mailbox.notifications.size.should==1
61
- receipt = @entity3.mailbox.notifications.first
62
- notification = receipt.notification
58
+ notification = @entity3.mailbox.notifications.first
63
59
  notification.subject.should=="Subject"
64
60
  notification.body.should=="Body"
65
61
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailboxer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
4
+ hash: 63
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 15
10
- version: 0.0.15
9
+ - 16
10
+ version: 0.0.16
11
11
  platform: ruby
12
12
  authors:
13
13
  - Eduardo Casanova Cuesta
@@ -15,12 +15,10 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-12 00:00:00 +02:00
18
+ date: 2011-04-17 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: foreigner
23
- prerelease: false
24
22
  requirement: &id001 !ruby/object:Gem::Requirement
25
23
  none: false
26
24
  requirements:
@@ -33,10 +31,10 @@ dependencies:
33
31
  - 1
34
32
  version: 0.9.1
35
33
  type: :runtime
34
+ name: foreigner
35
+ prerelease: false
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
38
- name: rails
39
- prerelease: false
40
38
  requirement: &id002 !ruby/object:Gem::Requirement
41
39
  none: false
42
40
  requirements:
@@ -49,10 +47,10 @@ dependencies:
49
47
  - 5
50
48
  version: 3.0.5
51
49
  type: :development
50
+ name: rails
51
+ prerelease: false
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
- name: sqlite3-ruby
55
- prerelease: false
56
54
  requirement: &id003 !ruby/object:Gem::Requirement
57
55
  none: false
58
56
  requirements:
@@ -63,10 +61,10 @@ dependencies:
63
61
  - 0
64
62
  version: "0"
65
63
  type: :development
64
+ name: sqlite3-ruby
65
+ prerelease: false
66
66
  version_requirements: *id003
67
67
  - !ruby/object:Gem::Dependency
68
- name: ruby-debug
69
- prerelease: false
70
68
  requirement: &id004 !ruby/object:Gem::Requirement
71
69
  none: false
72
70
  requirements:
@@ -79,10 +77,10 @@ dependencies:
79
77
  - 3
80
78
  version: 0.10.3
81
79
  type: :development
80
+ name: ruby-debug
81
+ prerelease: false
82
82
  version_requirements: *id004
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec-rails
85
- prerelease: false
86
84
  requirement: &id005 !ruby/object:Gem::Requirement
87
85
  none: false
88
86
  requirements:
@@ -95,10 +93,10 @@ dependencies:
95
93
  - 0
96
94
  version: 2.5.0
97
95
  type: :development
96
+ name: rspec-rails
97
+ prerelease: false
98
98
  version_requirements: *id005
99
99
  - !ruby/object:Gem::Dependency
100
- name: factory_girl
101
- prerelease: false
102
100
  requirement: &id006 !ruby/object:Gem::Requirement
103
101
  none: false
104
102
  requirements:
@@ -111,10 +109,10 @@ dependencies:
111
109
  - 2
112
110
  version: 1.3.2
113
111
  type: :development
112
+ name: factory_girl
113
+ prerelease: false
114
114
  version_requirements: *id006
115
115
  - !ruby/object:Gem::Dependency
116
- name: forgery
117
- prerelease: false
118
116
  requirement: &id007 !ruby/object:Gem::Requirement
119
117
  none: false
120
118
  requirements:
@@ -127,10 +125,10 @@ dependencies:
127
125
  - 6
128
126
  version: 0.3.6
129
127
  type: :development
128
+ name: forgery
129
+ prerelease: false
130
130
  version_requirements: *id007
131
131
  - !ruby/object:Gem::Dependency
132
- name: capybara
133
- prerelease: false
134
132
  requirement: &id008 !ruby/object:Gem::Requirement
135
133
  none: false
136
134
  requirements:
@@ -143,6 +141,8 @@ dependencies:
143
141
  - 9
144
142
  version: 0.3.9
145
143
  type: :development
144
+ name: capybara
145
+ prerelease: false
146
146
  version_requirements: *id008
147
147
  description: A Rails engine that allows any model to act as messageable, permitting it interchange messages with any other messageable model.It also supports sending system notifications to messageable models.
148
148
  email: ecasanovac@gmail.com