postman_pat 0.0.1.4

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 (104) hide show
  1. data/Gemfile +25 -0
  2. data/Gemfile.lock +145 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +3 -0
  5. data/Rakefile +34 -0
  6. data/app/assets/stylesheets/postman_pat/application.css +8 -0
  7. data/app/assets/stylesheets/postman_pat/postman_pat.css +16 -0
  8. data/app/controllers/postman_pat/pm_mails_controller.rb +107 -0
  9. data/app/controllers/postman_pat/pm_messages_controller.rb +4 -0
  10. data/app/models/postman_pat/pm_mail.rb +239 -0
  11. data/app/models/postman_pat/pm_message.rb +48 -0
  12. data/app/views/postman_pat/pm_mails/index.html.erb +14 -0
  13. data/app/views/postman_pat/pm_mails/new.html.erb +5 -0
  14. data/app/views/postman_pat/pm_mails/show.html.erb +10 -0
  15. data/config/routes.rb +10 -0
  16. data/doc/PostmanPat.html +176 -0
  17. data/doc/PostmanPat/ActsAsPostmanPat.html +106 -0
  18. data/doc/PostmanPat/ActsAsPostmanPat/Base.html +176 -0
  19. data/doc/PostmanPat/ActsAsPostmanPat/Base/ClassMethods.html +172 -0
  20. data/doc/PostmanPat/ActsAsPostmanPat/Base/InstanceMethods.html +107 -0
  21. data/doc/PostmanPat/Engine.html +116 -0
  22. data/doc/PostmanPat/PmMail.html +289 -0
  23. data/doc/PostmanPat/PmMessage.html +116 -0
  24. data/doc/_index.html +195 -0
  25. data/doc/class_list.html +47 -0
  26. data/doc/css/common.css +1 -0
  27. data/doc/css/full_list.css +53 -0
  28. data/doc/css/style.css +320 -0
  29. data/doc/file.README.html +70 -0
  30. data/doc/file_list.html +49 -0
  31. data/doc/frames.html +13 -0
  32. data/doc/index.html +70 -0
  33. data/doc/js/app.js +205 -0
  34. data/doc/js/full_list.js +150 -0
  35. data/doc/js/jquery.js +16 -0
  36. data/doc/method_list.html +78 -0
  37. data/doc/top-level-namespace.html +103 -0
  38. data/lib/acts_as_postman_pat/base.rb +36 -0
  39. data/lib/acts_as_postman_pat/exceptions.rb +4 -0
  40. data/lib/engine.rb +15 -0
  41. data/lib/generators/postman_pat/USAGE +8 -0
  42. data/lib/generators/postman_pat/postman_pat_generator.rb +23 -0
  43. data/lib/generators/postman_pat/templates/create_pm_mails_migration.rb +11 -0
  44. data/lib/generators/postman_pat/templates/create_pm_messages_migration.rb +14 -0
  45. data/lib/generators/postman_pat_generator.rb +20 -0
  46. data/lib/postman_pat.rb +5 -0
  47. data/lib/rails/railties/tasks.rake +4 -0
  48. data/spec/controllers/postman_pat/pm_mails_controller_spec.rb +215 -0
  49. data/spec/controllers/postman_pat/pm_messages_controller_spec.rb +22 -0
  50. data/spec/dummy/Rakefile +7 -0
  51. data/spec/dummy/app/assets/javascripts/application.js +7 -0
  52. data/spec/dummy/app/assets/stylesheets/application.css +73 -0
  53. data/spec/dummy/app/controllers/application_controller.rb +35 -0
  54. data/spec/dummy/app/controllers/users_controller.rb +22 -0
  55. data/spec/dummy/app/controllers/welcome_controller.rb +7 -0
  56. data/spec/dummy/app/helpers/application_helper.rb +19 -0
  57. data/spec/dummy/app/models/postman_pat.rb +5 -0
  58. data/spec/dummy/app/models/user.rb +12 -0
  59. data/spec/dummy/app/views/layouts/application.html.erb +39 -0
  60. data/spec/dummy/app/views/users/sign_in.html.erb +27 -0
  61. data/spec/dummy/app/views/welcome/index.html.erb +17 -0
  62. data/spec/dummy/config.ru +4 -0
  63. data/spec/dummy/config/application.rb +48 -0
  64. data/spec/dummy/config/boot.rb +10 -0
  65. data/spec/dummy/config/database.yml +16 -0
  66. data/spec/dummy/config/environment.rb +5 -0
  67. data/spec/dummy/config/environments/development.rb +27 -0
  68. data/spec/dummy/config/environments/production.rb +54 -0
  69. data/spec/dummy/config/environments/test.rb +39 -0
  70. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  71. data/spec/dummy/config/initializers/inflections.rb +10 -0
  72. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  73. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  74. data/spec/dummy/config/initializers/session_store.rb +8 -0
  75. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  76. data/spec/dummy/config/locales/en.yml +5 -0
  77. data/spec/dummy/config/routes.rb +59 -0
  78. data/spec/dummy/db/migrate/20110721115945_create_postman_pat_pm_mails.rb +11 -0
  79. data/spec/dummy/db/migrate/20110721154424_create_users.rb +13 -0
  80. data/spec/dummy/db/migrate/20110826002156_create_pm_messages.rb +11 -0
  81. data/spec/dummy/db/migrate/seeds.rb +9 -0
  82. data/spec/dummy/db/schema.rb +43 -0
  83. data/spec/dummy/lib/tasks/seed_users.rake +8 -0
  84. data/spec/dummy/log/development.log +8711 -0
  85. data/spec/dummy/log/test.log +91502 -0
  86. data/spec/dummy/public/404.html +26 -0
  87. data/spec/dummy/public/422.html +26 -0
  88. data/spec/dummy/public/500.html +26 -0
  89. data/spec/dummy/public/favicon.ico +0 -0
  90. data/spec/dummy/script/rails +6 -0
  91. data/spec/dummy/spec/models/user_spec.rb +5 -0
  92. data/spec/dummy/tmp/cache/assets/C51/060/sprockets%2Fe9f4825e0c80055b4424344b579d5063 +0 -0
  93. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  94. data/spec/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +0 -0
  95. data/spec/dummy/tmp/cache/assets/D76/D80/sprockets%2F09a58692f9fdff20fc0e3db456691c1a +0 -0
  96. data/spec/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +0 -0
  97. data/spec/dummy/tmp/cache/assets/DA5/060/sprockets%2F8257d949ce48ae1c1aace1e57a2a894e +0 -0
  98. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  99. data/spec/models/postman_pat/pm_mail_spec.rb +397 -0
  100. data/spec/models/postman_pat/pm_message_spec.rb +34 -0
  101. data/spec/spec.opts +2 -0
  102. data/spec/spec_helper.rb +131 -0
  103. data/spec/support/factories.rb +23 -0
  104. metadata +201 -0
data/Gemfile ADDED
@@ -0,0 +1,25 @@
1
+ source "http://rubygems.org"
2
+
3
+
4
+ # Bundle edge Rails instead:
5
+ # gem 'rails', :git => 'git://github.com/rails/rails.git'
6
+ gem 'acts_as_tree'
7
+ gem 'aasm'
8
+
9
+ group :development, :test do
10
+ gem 'mysql2'
11
+ gem 'jeweler'
12
+ gem 'ffaker'
13
+ gem 'yard'
14
+ gem 'rails', '3.1'
15
+ gem 'rspec-rails', '= 2.3'
16
+ #gem 'json_spec'
17
+ gem 'factory_girl_rails'
18
+ gem 'database_cleaner'
19
+ gem 'ruby-debug19'
20
+ gem 'mocha'
21
+ end
22
+
23
+ if RUBY_VERSION < '1.9'
24
+ gem "ruby-debug", ">= 0.10.3"
25
+ end
@@ -0,0 +1,145 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ aasm (2.3.0)
5
+ activerecord
6
+ actionmailer (3.1.0)
7
+ actionpack (= 3.1.0)
8
+ mail (~> 2.3.0)
9
+ actionpack (3.1.0)
10
+ activemodel (= 3.1.0)
11
+ activesupport (= 3.1.0)
12
+ builder (~> 3.0.0)
13
+ erubis (~> 2.7.0)
14
+ i18n (~> 0.6)
15
+ rack (~> 1.3.2)
16
+ rack-cache (~> 1.0.3)
17
+ rack-mount (~> 0.8.2)
18
+ rack-test (~> 0.6.1)
19
+ sprockets (~> 2.0.0)
20
+ activemodel (3.1.0)
21
+ activesupport (= 3.1.0)
22
+ bcrypt-ruby (~> 3.0.0)
23
+ builder (~> 3.0.0)
24
+ i18n (~> 0.6)
25
+ activerecord (3.1.0)
26
+ activemodel (= 3.1.0)
27
+ activesupport (= 3.1.0)
28
+ arel (~> 2.2.1)
29
+ tzinfo (~> 0.3.29)
30
+ activeresource (3.1.0)
31
+ activemodel (= 3.1.0)
32
+ activesupport (= 3.1.0)
33
+ activesupport (3.1.0)
34
+ multi_json (~> 1.0)
35
+ acts_as_tree (0.1.1)
36
+ archive-tar-minitar (0.5.2)
37
+ arel (2.2.1)
38
+ bcrypt-ruby (3.0.0)
39
+ builder (3.0.0)
40
+ columnize (0.3.4)
41
+ database_cleaner (0.6.7)
42
+ diff-lcs (1.1.3)
43
+ erubis (2.7.0)
44
+ factory_girl (2.1.0)
45
+ factory_girl_rails (1.2.0)
46
+ factory_girl (~> 2.1.0)
47
+ railties (>= 3.0.0)
48
+ ffaker (1.8.1)
49
+ git (1.2.5)
50
+ hike (1.2.1)
51
+ i18n (0.6.0)
52
+ jeweler (1.6.4)
53
+ bundler (~> 1.0)
54
+ git (>= 1.2.5)
55
+ rake
56
+ linecache19 (0.5.12)
57
+ ruby_core_source (>= 0.1.4)
58
+ mail (2.3.0)
59
+ i18n (>= 0.4.0)
60
+ mime-types (~> 1.16)
61
+ treetop (~> 1.4.8)
62
+ metaclass (0.0.1)
63
+ mime-types (1.16)
64
+ mocha (0.10.0)
65
+ metaclass (~> 0.0.1)
66
+ multi_json (1.0.3)
67
+ mysql2 (0.3.7)
68
+ polyglot (0.3.2)
69
+ rack (1.3.2)
70
+ rack-cache (1.0.3)
71
+ rack (>= 0.4)
72
+ rack-mount (0.8.3)
73
+ rack (>= 1.0.0)
74
+ rack-ssl (1.3.2)
75
+ rack
76
+ rack-test (0.6.1)
77
+ rack (>= 1.0)
78
+ rails (3.1.0)
79
+ actionmailer (= 3.1.0)
80
+ actionpack (= 3.1.0)
81
+ activerecord (= 3.1.0)
82
+ activeresource (= 3.1.0)
83
+ activesupport (= 3.1.0)
84
+ bundler (~> 1.0)
85
+ railties (= 3.1.0)
86
+ railties (3.1.0)
87
+ actionpack (= 3.1.0)
88
+ activesupport (= 3.1.0)
89
+ rack-ssl (~> 1.3.2)
90
+ rake (>= 0.8.7)
91
+ rdoc (~> 3.4)
92
+ thor (~> 0.14.6)
93
+ rake (0.9.2)
94
+ rdoc (3.9.4)
95
+ rspec (2.3.0)
96
+ rspec-core (~> 2.3.0)
97
+ rspec-expectations (~> 2.3.0)
98
+ rspec-mocks (~> 2.3.0)
99
+ rspec-core (2.3.1)
100
+ rspec-expectations (2.3.0)
101
+ diff-lcs (~> 1.1.2)
102
+ rspec-mocks (2.3.0)
103
+ rspec-rails (2.3.0)
104
+ actionpack (~> 3.0)
105
+ activesupport (~> 3.0)
106
+ railties (~> 3.0)
107
+ rspec (~> 2.3.0)
108
+ ruby-debug-base19 (0.11.25)
109
+ columnize (>= 0.3.1)
110
+ linecache19 (>= 0.5.11)
111
+ ruby_core_source (>= 0.1.4)
112
+ ruby-debug19 (0.11.6)
113
+ columnize (>= 0.3.1)
114
+ linecache19 (>= 0.5.11)
115
+ ruby-debug-base19 (>= 0.11.19)
116
+ ruby_core_source (0.1.5)
117
+ archive-tar-minitar (>= 0.5.2)
118
+ sprockets (2.0.0)
119
+ hike (~> 1.2)
120
+ rack (~> 1.0)
121
+ tilt (!= 1.3.0, ~> 1.1)
122
+ thor (0.14.6)
123
+ tilt (1.3.3)
124
+ treetop (1.4.10)
125
+ polyglot
126
+ polyglot (>= 0.3.1)
127
+ tzinfo (0.3.29)
128
+ yard (0.7.2)
129
+
130
+ PLATFORMS
131
+ ruby
132
+
133
+ DEPENDENCIES
134
+ aasm
135
+ acts_as_tree
136
+ database_cleaner
137
+ factory_girl_rails
138
+ ffaker
139
+ jeweler
140
+ mocha
141
+ mysql2
142
+ rails (= 3.1)
143
+ rspec-rails (= 2.3)
144
+ ruby-debug19
145
+ yard
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ = PostmanPat
2
+
3
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'PostmanPat'
18
+ rdoc.options << '--line-numbers' << '--inline-source'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task :default => :test
@@ -0,0 +1,8 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
8
+
@@ -0,0 +1,16 @@
1
+ /* ------------------------------------------------------------------------------------- */
2
+ /* Postman Pat Private Message Styles */
3
+ /* Author: Kirk v. Quesnelle
4
+ /* Last updated: Monday Sept. 5th 2011
5
+ /* ------------------------------------------------------------------------------------- */
6
+ div#pmp_mail_summary_container
7
+ {
8
+
9
+ }
10
+ div.pmp_mail_summary_block
11
+ {
12
+ border: 1px dotted #AAA;
13
+ padding: 8px;
14
+ }
15
+
16
+
@@ -0,0 +1,107 @@
1
+
2
+ class PostmanPat::PmMailsController < ApplicationController
3
+ before_filter :redirect_nologin
4
+
5
+ def index
6
+ @title = "Private Messages"
7
+ @pm_mails = PostmanPat::PmMail.get_all_mail(current_user.id)
8
+
9
+ respond_to do |format|
10
+ format.html
11
+ format.json { render :json => @pm_mails.to_json }
12
+ end
13
+ end
14
+
15
+ def show
16
+ @pm_mail = PostmanPat::PmMail.get_mail(current_user.id, (params[:id]).to_i)
17
+
18
+ if @pm_mail.nil?
19
+ flash[:error] = "Private message no longer exists."
20
+ redirect_to '/' and return
21
+ end
22
+
23
+ # Mark the mail as read
24
+ @pm_mail.mark_read!
25
+
26
+ @title = "Private Message: #{@pm_mail.pm_message.subject}"
27
+
28
+ respond_to do |format|
29
+ format.html
30
+ format.json { render :json => @pm_mail.to_json }
31
+ end
32
+ end
33
+
34
+ def new
35
+ @title = "New Private Message"
36
+ @pm_mail = PostmanPat::PmMail.new
37
+ end
38
+
39
+ def create
40
+ success = true
41
+ recipients = params[:recipients]
42
+ subject = params[:subject]
43
+ message = params[:message]
44
+
45
+ #[TODO] - do proper exception checking
46
+ begin
47
+ result = PostmanPat::PmMail.compose(current_user, recipients, subject, message)
48
+ flash[:success] = "Message has been sent."
49
+ rescue Exception, "An error has occured with PmMail.compose method"
50
+ success = false
51
+ flash[:error] = "There was a problem sending your message."
52
+ end
53
+
54
+ respond_to do |format|
55
+ format.html { redirect_to mail_index_path }
56
+ format.json { render :json => "{\"success\":#{success}}"}
57
+ end
58
+ end
59
+
60
+ def update
61
+ success = true
62
+ pm_mail = PostmanPat::PmMail.get_mail(current_user.id, (params[:id]).to_i)
63
+
64
+ #[TODO] - do proper exception checking
65
+ begin
66
+ pm_mail.reply(params[:message])
67
+ flash[:success] = "Reply has been sent."
68
+ rescue Exception
69
+ success = false
70
+ flash[:error] = "There was a probly sending your reply."
71
+ end
72
+
73
+ respond_to do |format|
74
+ format.html { redirect_to mail_index_path }
75
+ format.json { render :json => "{\"success\":#{success}}"}
76
+ end
77
+ end
78
+
79
+ def destroy
80
+ success = true
81
+ pm_mail = PostmanPat::PmMail.get_mail(current_user.id, params[:id])
82
+
83
+ #[TODO] - do proper exception checking
84
+ begin
85
+ pm_mail.mark_deleted!
86
+ flash[:success] = "Your reply has been sent."
87
+ rescue Exception
88
+ success = false
89
+ flash[:error] = "There was an error sending your reply."
90
+ end
91
+
92
+ respond_to do |format|
93
+ format.html { redirect_to mail_index_path }
94
+ format.json { render :json => "{\"success\":#{success}}"}
95
+ end
96
+ end
97
+
98
+ private
99
+
100
+ def redirect_nologin
101
+ if current_user.nil?
102
+ flash[:error] = "You must be signed in to access Private Messaging"
103
+ redirect_to '/' and return
104
+ end
105
+ end
106
+
107
+ end
@@ -0,0 +1,4 @@
1
+ class PostmanPat::PmMessagesController < ApplicationController
2
+
3
+ end
4
+
@@ -0,0 +1,239 @@
1
+ require 'aasm'
2
+ module PostmanPat
3
+
4
+ class PmMail < ActiveRecord::Base
5
+ include ::AASM
6
+
7
+ # --------------------------------------------------------------------------------------------------
8
+ # Relationships
9
+ # --------------------------------------------------------------------------------------------------
10
+ # [TODO] :class_name will have to be dynamic based on what model called
11
+ # acts_as_postman_pat, as well as :foreign_key
12
+ belongs_to :recipient, :class_name => "User"
13
+ belongs_to :pm_message, :class_name => "PostmanPat::PmMessage"
14
+
15
+ #accepts_nested_attributes_for :pm_message
16
+
17
+ # --------------------------------------------------------------------------------------------------
18
+ # Validations
19
+ # --------------------------------------------------------------------------------------------------
20
+ validates :recipient_id, :presence => true
21
+ validates :pm_message, :presence => true
22
+
23
+ # --------------------------------------------------------------------------------------------------
24
+ # State Machine
25
+ # --------------------------------------------------------------------------------------------------
26
+ # [TODO] - write test for state machine transitions
27
+ aasm_initial_state :unread
28
+
29
+ aasm_state :unread
30
+ aasm_state :read
31
+ aasm_state :sent
32
+ aasm_state :deleted
33
+
34
+ # State Transitions Events
35
+ aasm_event :mark_read do
36
+ transitions :to => :read, :from => [:unread, :read, :sent, :deleted]
37
+ end
38
+
39
+ aasm_event :mark_unread do
40
+ transitions :to => :unread, :from => [:deleted, :read, :unread, :sent]
41
+ end
42
+
43
+ aasm_event :mark_sent do
44
+ transitions :to => :sent, :from => [:unread, :delete, :read, :sent]
45
+ end
46
+
47
+ aasm_event :mark_deleted do
48
+ transitions :to => :deleted, :from => [:read, :unread, :deleted, :sent]
49
+ end
50
+
51
+ # --------------------------------------------------------------------------------------------------
52
+ # Class Methods
53
+ # --------------------------------------------------------------------------------------------------
54
+
55
+ # Creates and sends a new Private Message with subject and message to all recipients
56
+ #
57
+ # @param [User] user the sender of this message.
58
+ # @param [Array] recipients user account ids that are to receive the message
59
+ # @param [optional, String] subject an optional subject for the new message. If no subject is given a default message of "[No Subject]" is provided.
60
+ # @param [String] message the message content
61
+ # @return [PmMessage] PmMessage object
62
+ def self.compose(author, recipients, subject, message)
63
+ recipients.map {|r| r.to_i}
64
+
65
+ # Add default subject if non is provided
66
+ subject = "[No Subject]" if subject.blank?
67
+
68
+ msg = PostmanPat::PmMessage.new
69
+ msg.author = author
70
+ msg.subject = subject
71
+ msg.message = message
72
+
73
+ transaction do
74
+ msg.save!
75
+ # send a copy of the mail to the creator of the message and mark it as sent
76
+ mail = PostmanPat::PmMail.new
77
+ mail.recipient = author
78
+ mail.pm_message = msg
79
+ mail.mark_sent!
80
+ mail.save!
81
+
82
+ # create a new piece of mail for each collaborator in the message
83
+ recipients.each do |recipient|
84
+ mail = PostmanPat::PmMail.new
85
+ mail.recipient_id = recipient
86
+ mail.pm_message = msg
87
+ mail.save!
88
+ end # each loop
89
+ end # transaction
90
+ msg
91
+ end
92
+
93
+ # Gets a specific pm mail by the user_id and mail_id
94
+ #
95
+ # @param [Integer] user_id the user id of the user to collect all mail for
96
+ # @param [Integer] mail_id the PmMail instance id of the mail you're trying to find
97
+ # @return [PmMail] PmMail instance or nil if the mail message of the user can not be found
98
+ def self.get_mail(user_id, mail_id)
99
+ where(:id => mail_id).where(:recipient_id => user_id).first
100
+ end
101
+
102
+ # Gets all PmMail's for a user
103
+ #
104
+ # @param [Integer] user_id the user id of the user to fetch all the mail for
105
+ # @return [Array] an array of PmMail instances
106
+ def self.get_all_mail(user_id)
107
+ where(:recipient_id => user_id)
108
+ end
109
+
110
+
111
+ # Returns the total number of private mails for a particular user
112
+ #
113
+ # @param [Integer] user_id user id of the user to find the total number of unread mails for
114
+ # @returns [Integer] the total number of mails
115
+ def self.num_mail(user_id)
116
+ where(:recipient_id => user_id).count
117
+ end
118
+
119
+
120
+ # Returns the number of unread private mail for a particular user
121
+ #
122
+ # @param [Integer] user_id user id of the user to find the number of unread mails for
123
+ # @returns [Integer] the number of unread mails.
124
+ def self.num_unread_mail(user_id)
125
+ where(:recipient_id => user_id).where(:aasm_state => 'unread').count
126
+ end
127
+
128
+ # Returns the number of read private mail for a particular user
129
+ #
130
+ # @param [Integer] user_id user id of the user to find the number of read mails for
131
+ # @returns [Integer] the number of read mails.
132
+ def self.num_read_mail(user_id)
133
+ where(:recipient_id => user_id).where(:aasm_state => 'read').count
134
+ end
135
+
136
+ # Returns the number of deleted private mail for a particular user
137
+ #
138
+ # @param [Integer] user_id user id of the user to find the number of deleted mails for
139
+ # @returns [Integer] the number of deleted mails.
140
+ def self.num_deleted_mail(user_id)
141
+ where(:recipient_id => user_id).where(:aasm_state => 'deleted').count
142
+ end
143
+
144
+
145
+ # --------------------------------------------------------------------------------------------------
146
+ # Instance Methods
147
+ # --------------------------------------------------------------------------------------------------
148
+
149
+ # Return true or false if the mail is unread or not
150
+ #
151
+ # @returns [Boolean] true if the mail is unread, false otherwise
152
+ def is_unread?
153
+ self.aasm_state == "unread"
154
+ end
155
+
156
+ # Return true or false if the mail has been read or not
157
+ #
158
+ # @returns [Boolean] true if the mail has been read, false otherwise
159
+ def is_read?
160
+ self.aasm_state == "read"
161
+ end
162
+
163
+ # Return true or false if the mail is in a state of sent
164
+ #
165
+ # @returns [Boolean] true if the mail is the state of sent
166
+ def is_sent?
167
+ self.aasm_state == "sent"
168
+ end
169
+
170
+ # Return true or false if the mail has been deleted
171
+ #
172
+ # @returns [Boolean] true if the mail has been deleted by user
173
+ def is_deleted?
174
+ self.aasm_state == "deleted"
175
+ end
176
+
177
+ # Reply to the mail message thread.
178
+ #
179
+ # @param [String] message the reply message
180
+ def reply(message)
181
+ reply = PostmanPat::PmMessage.new
182
+ reply.parent_id = self.pm_message_id
183
+ reply.author_id = self.recipient_id
184
+ reply.message = message
185
+
186
+ if reply.save!
187
+ # Set the message as unread again for all collaborators of the mail thread because
188
+ # one of them replied, thus making the mail "new" or "unseen" by all collaborators
189
+ set_all_to_unread
190
+
191
+ # Set the senders message state to 'sent'
192
+ self.mark_sent!
193
+ end
194
+
195
+ end
196
+
197
+ # Tell us who the last user was to reply to the PmMail message thread.
198
+ # If nobody has replied, the author will be returned.
199
+ #
200
+ # @return [User] the last user to reply. Returns the author of the message if nobody has replied yet
201
+ def who_last_replied?
202
+ pm_message = PostmanPat::PmMessage.find(self.pm_message_id)
203
+ # [TODO] - raise exception if pm_message is nil
204
+
205
+ if pm_message.children.count > 0
206
+ # [TODO] - link up the account/user model to be dynamic on whatever model called acts_as_postman_pat
207
+ User.find(pm_message.children.last.author_id)
208
+ else
209
+ # if nobody has replied, return creator
210
+ User.find(pm_message.author_id)
211
+ end
212
+
213
+ end
214
+
215
+ # Returns all the collaborators(users) of the PmMail/Message thread
216
+ #
217
+ # @return [Array] array of users who are collaborating on the private message thread
218
+ def all_collaborators
219
+ collaborators = PostmanPat::PmMail.where(:pm_message_id => self.pm_message_id)
220
+ ids = []
221
+ collaborators.each do |c|
222
+ ids << c.recipient_id
223
+ end
224
+ User.where(:id => ids)
225
+ end
226
+
227
+ private
228
+
229
+ # Set all mail of a given message thread to unread.
230
+ # @private
231
+ def set_all_to_unread
232
+ mails = PmMail.find_all_by_pm_message_id(self.pm_message_id)
233
+ mails.each do |mail|
234
+ mail.mark_unread!
235
+ end
236
+ end
237
+
238
+ end
239
+ end