mailboxer 0.10.3 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd3c7b425e191ba6788668307d71c0a472d0db03
4
- data.tar.gz: f9910f2a5eae2f12f4daf3a56c5654b89bf8e716
3
+ metadata.gz: b22e110378d5da7e6e327c807f46a5f0475b2fa1
4
+ data.tar.gz: bc9242e076e3a10d2e3d9ca1106a42200ca7bc12
5
5
  SHA512:
6
- metadata.gz: a0fcdb2b6596e63d82183fbf73f758fb0755bfe2afe1c7e9939a041e35b2959c37bcfa41aceecac62314d16967bf6e77a9dd628d7d7c58361a34b76d82e603d5
7
- data.tar.gz: c3ab6f97dfaf4dd8b808cd52f8c66551a576a554231c0a6142d7d37b715e4c04abcc14eb1f7c71ea3590ed494b03de21990cc8834a45f9b6c32c3fb6c3874ce9
6
+ metadata.gz: f67c3839eb84ce3153e7e9b1b50b012f80a1d17bdb56589e18279ba1043e3e4fc4f443c17b2ed9cff7a0e4bcbc9ebef10139bd63de67b520ac12f3fcd40bc05e
7
+ data.tar.gz: 277d0c3921688613e407b095665d7d2b2afe783294f1500d9ba2a423c83460b5854711520a9cfaddcec876b864924c65136edcd78dbdad4fbbd8286eb5d5405f
data/.travis.yml CHANGED
@@ -1,10 +1,11 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.8.7
4
- - 1.9.2
5
3
  - 1.9.3
6
- - ree
7
- - rbx-18mode
4
+ - 2.0.0
8
5
  - rbx-19mode
9
- - jruby-18mode
10
6
  - jruby-19mode
7
+ gemfile:
8
+ #- gemfiles/rails3.0.gemfile
9
+ - gemfiles/rails3.1.gemfile
10
+ - gemfiles/rails3.2.gemfile
11
+ - gemfiles/rails4.0.gemfile
data/Appraisals ADDED
@@ -0,0 +1,19 @@
1
+ # appraise "rails3.0" do
2
+ # gem "rails", "~> 3.0.15"
3
+ # gem "mailboxer", :path => "../"
4
+ # end
5
+
6
+ appraise "rails3.1" do
7
+ gem "rails", "~> 3.1.6"
8
+ gem "mailboxer", :path => "../"
9
+ end
10
+
11
+ appraise "rails3.2" do
12
+ gem "rails", "~> 3.2.6"
13
+ gem "mailboxer", :path => "../"
14
+ end
15
+
16
+ appraise "rails4.0" do
17
+ gem "rails", ">=4.0.0"
18
+ gem "mailboxer", :path => "../"
19
+ end
data/LICENSE.txt CHANGED
@@ -1,3 +1,4 @@
1
+ Copyright (c) 2013 Justin Coyne
1
2
  Copyright (c) 2012 Universidad Politécnica de Madrid
2
3
 
3
4
  Permission is hereby granted, free of charge, to any person obtaining
data/README.md CHANGED
@@ -1,31 +1,31 @@
1
- # Mailboxer 0.10.x [![](https://secure.travis-ci.org/ging/mailboxer.png)](http://travis-ci.org/ging/mailboxer) [![](https://gemnasium.com/ging/mailboxer.png)](https://gemnasium.com/ging/mailboxer)
1
+ # Mailboxer 0.10.x [![](https://secure.travis-ci.org/ging/mailboxer.png)](http://travis-ci.org/ging/mailboxer) [![Gem Version](https://badge.fury.io/rb/mailboxer.png)](http://badge.fury.io/rb/mailboxer) [![](https://gemnasium.com/ging/mailboxer.png)](https://gemnasium.com/ging/mailboxer)
2
2
 
3
- This project is based on the need of a private message system for [ging
3
+ This project is based on the need for a private message system for [ging
4
4
  / social\_stream](https://github.com/ging/social_stream). Instead of creating our core message system heavily
5
- dependent on our development we are trying to implement a generic and
5
+ dependent on our development, we are trying to implement a generic and
6
6
  potent messaging gem.
7
7
 
8
- After looking for a good gem to use we notice the lack of messaging gems
9
- and functionality in them. Mailboxer tries to fill this emptiness giving
10
- a powerfull and generic message system. It supports the use of
11
- conversations with two or more recipients, send notification to a
12
- recipient (intended to be used as system notifications “Your picture has
13
- new comments”, “John Doe has updated its document”, etc.), emails the
14
- messageable model (if configured to do so). It has a complete use of a
15
- `Mailbox` object for each messageable with `inbox`, `sentbox` and
8
+ After looking for a good gem to use we noticed the lack of messaging gems
9
+ and functionality in them. Mailboxer tries to fill this void delivering
10
+ a powerful and flexible message system. It supports the use of
11
+ conversations with two or more participants, sending notifications to
12
+ recipients (intended to be used as system notifications “Your picture has
13
+ new comments”, “John Doe has updated his document”, etc.), and emailing the
14
+ messageable model (if configured to do so). It has a complete implementation
15
+ of a `Mailbox` object for each messageable with `inbox`, `sentbox` and
16
16
  `trash`.
17
17
 
18
18
  The gem is constantly growing and improving its functionality. As it is
19
19
  used with our parallel development [ging / social\_stream](https://github.com/ging/social_stream) we are finding and fixing bugs continously. If you want
20
20
  some functionality not supported yet or marked as TODO, you can create
21
- an [issue](https://github.com/ging/mailboxer/issues) to ask for it. It will be a great feedback for us, and we
22
- will know what you may find useful of the gem.
21
+ an [issue](https://github.com/ging/mailboxer/issues) to ask for it. It will be great feedback for us, and we
22
+ will know what you may find useful in the gem.
23
23
 
24
24
  Mailboxer was born from the great, but outdated, code from [lpsergi /
25
25
  acts*as*messageable](https://github.com/psergi/acts_as_messageable).
26
26
 
27
- We are now working to make an exhaustive documentation and some wiki
28
- pages in order to make even easier to use the gem at its full potencial.
27
+ We are now working to make exhaustive documentation and some wiki
28
+ pages in order to make it even easier to use the gem to its full potencial.
29
29
  Please, give us some time if you find something missing or [ask for
30
30
  it](https://github.com/ging/mailboxer/issues).
31
31
 
@@ -50,7 +50,7 @@ Run install script:
50
50
  $ rails g mailboxer:install
51
51
  ```
52
52
 
53
- And don't forget to migrate you database:
53
+ And don't forget to migrate your database:
54
54
 
55
55
  ```sh
56
56
  $ rake db:migrate
@@ -60,19 +60,19 @@ $ rake db:migrate
60
60
 
61
61
  ### Emails
62
62
 
63
- We are now adding support for sending emails when a Notification or a Message is sent to one or more recipients. You should modify mailboxer initializer (/config/initializer/mailboxer.rb) to edit this settings.
63
+ We are now adding support for sending emails when a Notification or a Message is sent to one or more recipients. You should modify the mailboxer initializer (/config/initializer/mailboxer.rb) to edit these settings.
64
64
 
65
65
  ```ruby
66
66
  Mailboxer.setup do |config|
67
- #Configures if you applications uses or no the email sending for Notifications and Messages
67
+ #Enables or disables email sending for Notifications and Messages
68
68
  config.uses_emails = true
69
- #Configures the default from for the email sent for Messages and Notifications of Mailboxer
69
+ #Configures the default `from` address for the email sent for Messages and Notifications of Mailboxer
70
70
  config.default_from = "no-reply@dit.upm.es"
71
71
  ...
72
72
  end
73
73
  ```
74
74
 
75
- You can change the way in which emails are delivered by specifying a custom implementation for notification and message mailer
75
+ You can change the way in which emails are delivered by specifying a custom implementation of notification and message mailers
76
76
 
77
77
  ```ruby
78
78
  Mailboxer.setup do |config|
@@ -84,7 +84,7 @@ end
84
84
 
85
85
  ### User identities
86
86
 
87
- Users must have an identity defined by a `name` and an `email`. We must assure that Messageable models have some specific methods. These methods are:
87
+ Users must have an identity defined by a `name` and an `email`. We must ensure that Messageable models have some specific methods. These methods are:
88
88
 
89
89
  ```ruby
90
90
  #Returning any kind of identification you want for the model
@@ -126,7 +126,7 @@ config.name_method = :display_name
126
126
 
127
127
  Will use the method `notification_email(object)` instead of `mailboxer_email(object)` and `display_name` for `name`.
128
128
 
129
- Using default or custom method names, if your model doesn't implement them, Mailboxer will use dummy methods not to crash but notify you the missing methods.
129
+ Using default or custom method names, if your model doesn't implement them, Mailboxer will use dummy methods so as to notify you of missing methods rather than crashing.
130
130
 
131
131
  ## Preparing your models
132
132
 
@@ -138,7 +138,7 @@ class User < ActiveRecord::Base
138
138
  end
139
139
  ```
140
140
 
141
- You are not limited to User model. You can use Mailboxer in any other model and use it in serveral different models. If you have ducks and cylons in your application and you want to interchange messages as if they where the same, just use act_as_messageable in each one and you will be able to send duck-duck, duck-cylon, cylon-duck and cylon-cylon messages. Of course, you can extend it for as many clases as you need.
141
+ You are not limited to the User model. You can use Mailboxer in any other model and use it in serveral different models. If you have ducks and cylons in your application and you want to exchange messages as if they were the same, just add `acts_as_messageable` to each one and you will be able to send duck-duck, duck-cylon, cylon-duck and cylon-cylon messages. Of course, you can extend it for as many classes as you need.
142
142
 
143
143
  Example:
144
144
 
@@ -199,6 +199,25 @@ alfa.mailbox.sentbox
199
199
  alfa.mailbox.trash
200
200
  ```
201
201
 
202
+ ### How can I delete a message from trash?
203
+
204
+ ```ruby
205
+ #delete conversations forever for one receipt (still in database)
206
+ receipt.mark_as_deleted
207
+
208
+ #you can mark conversation as deleted for one participant
209
+ conversation.mark_as_deleted participant
210
+
211
+ #Mark the object as deleted for messageable
212
+ #Object can be:
213
+ #* A Receipt
214
+ #* A Conversation
215
+ #* A Notification
216
+ #* A Message
217
+ #* An array with any of them
218
+ alfa.mark_as_deleted conversation
219
+ ```
220
+
202
221
  ### How can I paginate conversations?
203
222
 
204
223
  You can use Kaminari to paginate the conversations as normal. Please, make sure you use the last version as mailboxer uses `select('DISTINCT conversations.*')` which was not respected before Kaminari 0.12.4 according to its changelog. Working corretly on Kaminari 0.13.0.
@@ -219,7 +238,7 @@ conversations = alfa.mailbox.trash.page(params[:page]).per(9)
219
238
 
220
239
  ### How can I read the messages of a conversation?
221
240
 
222
- As a messageable, what you receive receipts wich are linked with the message itself. You should retrieve your receipts for the conversation a get the message associated to them.
241
+ As a messageable, what you receive are receipts, which are associated with the message itself. You should retrieve your receipts for the conversation a get the message associated with them.
223
242
 
224
243
  This is done this way because receipts save the information about the relation between messageable and the messages: is it read?, is it trashed?, etc.
225
244
 
@@ -239,7 +258,7 @@ receipts.each do |receipt|
239
258
  end
240
259
  ```
241
260
 
242
- You can take a look at the full documentation of Mailboxer in [rubydoc.info](http://rubydoc.info/gems/mailboxer/frames).
261
+ You can take a look at the full documentation for Mailboxer in [rubydoc.info](http://rubydoc.info/gems/mailboxer/frames).
243
262
 
244
263
  ## Do you want to test Mailboxer?
245
264
 
@@ -247,7 +266,7 @@ Thanks to [Roman Kushnir (@RKushnir)](https://github.com/RKushnir/) you can test
247
266
 
248
267
  ## I need a GUI!
249
268
 
250
- If you need a GUI you should take a look a this links:
269
+ If you need a GUI you should take a look a these links:
251
270
 
252
271
  * The [rails-messaging](https://github.com/frodefi/rails-messaging) project.
253
272
  * The wiki page [GUI Example on a real application](https://github.com/ging/mailboxer/wiki/GUI-Example-on-a-real-application).
data/Rakefile CHANGED
@@ -1,5 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
1
4
  require "bundler/gem_tasks"
2
5
 
6
+ require 'appraisal'
3
7
  require 'rspec/core'
4
8
  require 'rspec/core/rake_task'
5
9
  RSpec::Core::RakeTask.new(:spec)
@@ -1,16 +1,16 @@
1
1
  class MessageMailer < ActionMailer::Base
2
2
  default :from => Mailboxer.default_from
3
- #Sends and email for indicating a new message or a reply to a receiver.
3
+ #Sends and email for indicating a new message or a reply to a receiver.
4
4
  #It calls new_message_email if notifing a new message and reply_message_email
5
5
  #when indicating a reply to an already created conversation.
6
- def send_email(message,receiver)
7
- if message.conversation.messages.size > 1
6
+ def send_email(message, receiver)
7
+ if message.conversation.messages.size > 1
8
8
  reply_message_email(message,receiver)
9
9
  else
10
10
  new_message_email(message,receiver)
11
11
  end
12
12
  end
13
-
13
+
14
14
  include ActionView::Helpers::SanitizeHelper
15
15
 
16
16
  #Sends an email for indicating a new message for the receiver
@@ -1,24 +1,24 @@
1
1
  class Conversation < ActiveRecord::Base
2
- attr_accessible :subject
2
+ attr_accessible :subject if Mailboxer.protected_attributes?
3
3
 
4
- has_many :messages, :dependent => :destroy
5
- has_many :receipts, :through => :messages
4
+ has_many :messages, :dependent => :destroy
5
+ has_many :receipts, :through => :messages
6
6
 
7
- validates_presence_of :subject
7
+ validates_presence_of :subject
8
8
 
9
- before_validation :clean
9
+ before_validation :clean
10
10
 
11
11
  scope :participant, lambda {|participant|
12
12
  select('DISTINCT conversations.*').
13
- where('notifications.type'=> Message.name).
14
- order("conversations.updated_at DESC").
15
- joins(:receipts).merge(Receipt.recipient(participant))
13
+ where('notifications.type'=> Message.name).
14
+ order("conversations.updated_at DESC").
15
+ joins(:receipts).merge(Receipt.recipient(participant))
16
16
  }
17
17
  scope :inbox, lambda {|participant|
18
- participant(participant).merge(Receipt.inbox.not_trash)
18
+ participant(participant).merge(Receipt.inbox.not_trash.not_deleted)
19
19
  }
20
20
  scope :sentbox, lambda {|participant|
21
- participant(participant).merge(Receipt.sentbox.not_trash)
21
+ participant(participant).merge(Receipt.sentbox.not_trash.not_deleted)
22
22
  }
23
23
  scope :trash, lambda {|participant|
24
24
  participant(participant).merge(Receipt.trash)
@@ -31,113 +31,136 @@ class Conversation < ActiveRecord::Base
31
31
  }
32
32
 
33
33
  #Mark the conversation as read for one of the participants
34
- def mark_as_read(participant)
35
- return if participant.nil?
36
- return self.receipts_for(participant).mark_as_read
37
- end
34
+ def mark_as_read(participant)
35
+ return if participant.nil?
36
+ self.receipts_for(participant).mark_as_read
37
+ end
38
38
 
39
39
  #Mark the conversation as unread for one of the participants
40
- def mark_as_unread(participant)
41
- return if participant.nil?
42
- return self.receipts_for(participant).mark_as_unread
43
- end
40
+ def mark_as_unread(participant)
41
+ return if participant.nil?
42
+ self.receipts_for(participant).mark_as_unread
43
+ end
44
44
 
45
45
  #Move the conversation to the trash for one of the participants
46
- def move_to_trash(participant)
47
- return if participant.nil?
48
- return self.receipts_for(participant).move_to_trash
49
- end
46
+ def move_to_trash(participant)
47
+ return if participant.nil?
48
+ self.receipts_for(participant).move_to_trash
49
+ end
50
50
 
51
51
  #Takes the conversation out of the trash for one of the participants
52
- def untrash(participant)
53
- return if participant.nil?
54
- return self.receipts_for(participant).untrash
55
- end
52
+ def untrash(participant)
53
+ return if participant.nil?
54
+ self.receipts_for(participant).untrash
55
+ end
56
56
 
57
- #Returns an array of participants
58
- def recipients
59
- if self.last_message
60
- recps = self.last_message.recipients
61
- recps = recps.is_a?(Array) ? recps : [recps]
62
- return recps
63
- end
64
- return []
65
- end
57
+ #Mark the conversation as deleted for one of the participants
58
+ def mark_as_deleted(participant)
59
+ return if participant.nil?
60
+ return self.receipts_for(participant).mark_as_deleted
61
+ end
66
62
 
67
63
  #Returns an array of participants
68
- def participants
69
- return recipients
70
- end
71
-
72
- #Originator of the conversation.
73
- def originator
74
- @originator = self.original_message.sender if @originator.nil?
75
- return @originator
76
- end
77
-
78
- #First message of the conversation.
79
- def original_message
80
- @original_message = self.messages.find(:first, :order => 'created_at') if @original_message.nil?
81
- return @original_message
82
- end
83
-
84
- #Sender of the last message.
85
- def last_sender
86
- @last_sender = self.last_message.sender if @last_sender.nil?
87
- return @last_sender
88
- end
64
+ def recipients
65
+ if self.last_message
66
+ recps = self.last_message.recipients
67
+ recps = recps.is_a?(Array) ? recps : [recps]
68
+ recps
69
+ else
70
+ []
71
+ end
72
+ end
89
73
 
90
- #Last message in the conversation.
91
- def last_message
92
- @last_message = self.messages.find(:first, :order => 'created_at DESC') if @last_message.nil?
93
- return @last_message
94
- end
74
+ #Returns an array of participants
75
+ def participants
76
+ recipients
77
+ end
78
+
79
+ #Originator of the conversation.
80
+ def originator
81
+ @originator ||= self.original_message.sender
82
+ end
83
+
84
+ #First message of the conversation.
85
+ def original_message
86
+ @original_message ||= self.messages.order('created_at').first
87
+ end
88
+
89
+ #Sender of the last message.
90
+ def last_sender
91
+ @last_sender ||= self.last_message.sender
92
+ end
93
+
94
+ #Last message in the conversation.
95
+ def last_message
96
+ @last_message ||= self.messages.order('created_at DESC').first
97
+ end
95
98
 
96
99
  #Returns the receipts of the conversation for one participants
97
- def receipts_for(participant)
98
- return Receipt.conversation(self).recipient(participant)
99
- end
100
+ def receipts_for(participant)
101
+ Receipt.conversation(self).recipient(participant)
102
+ end
100
103
 
101
104
  #Returns the number of messages of the conversation
102
- def count_messages
103
- return Message.conversation(self).count
104
- end
105
+ def count_messages
106
+ Message.conversation(self).count
107
+ end
105
108
 
106
109
  #Returns true if the messageable is a participant of the conversation
107
- def is_participant?(participant)
108
- return false if participant.nil?
109
- return self.receipts_for(participant).count != 0
110
+ def is_participant?(participant)
111
+ return false if participant.nil?
112
+ self.receipts_for(participant).count != 0
113
+ end
114
+
115
+ #Adds a new participant to the conversation
116
+ def add_participant(participant)
117
+ messages = self.messages
118
+ messages.each do |message|
119
+ receipt = Receipt.new
120
+ receipt.notification = message
121
+ receipt.is_read = false
122
+ receipt.receiver = participant
123
+ receipt.mailbox_type = 'inbox'
124
+ receipt.updated_at = message.updated_at
125
+ receipt.created_at = message.created_at
126
+ receipt.save
127
+ end
110
128
  end
111
129
 
112
130
  #Returns true if the participant has at least one trashed message of the conversation
113
- def is_trashed?(participant)
114
- return false if participant.nil?
115
- return self.receipts_for(participant).trash.count!=0
116
- end
131
+ def is_trashed?(participant)
132
+ return false if participant.nil?
133
+ self.receipts_for(participant).trash.count != 0
134
+ end
135
+
136
+ #Returns true if the participant has deleted the conversation
137
+ def is_deleted?(participant)
138
+ return false if participant.nil?
139
+ return self.receipts_for(participant).trash.count==0
140
+ end
117
141
 
118
142
  #Returns true if the participant has trashed all the messages of the conversation
119
- def is_completely_trashed?(participant)
120
- return false if participant.nil?
121
- return self.receipts_for(participant).trash.count == self.receipts_for(participant).count
122
- end
143
+ def is_completely_trashed?(participant)
144
+ return false if participant.nil?
145
+ self.receipts_for(participant).trash.count == self.receipts_for(participant).count
146
+ end
123
147
 
124
- def is_read?(participant)
125
- !self.is_unread?(participant)
126
- end
148
+ def is_read?(participant)
149
+ !self.is_unread?(participant)
150
+ end
127
151
 
128
152
  #Returns true if the participant has at least one unread message of the conversation
129
- def is_unread?(participant)
130
- return false if participant.nil?
131
- return self.receipts_for(participant).not_trash.is_unread.count!=0
132
- end
153
+ def is_unread?(participant)
154
+ return false if participant.nil?
155
+ self.receipts_for(participant).not_trash.is_unread.count != 0
156
+ end
133
157
 
134
- protected
158
+ protected
135
159
 
136
- include ActionView::Helpers::SanitizeHelper
160
+ include ActionView::Helpers::SanitizeHelper
137
161
 
138
162
  #Use the default sanitize to clean the conversation subject
139
- def clean
140
- self.subject = sanitize self.subject
141
- end
142
-
163
+ def clean
164
+ self.subject = sanitize self.subject
165
+ end
143
166
  end