postman_pat 0.0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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