facteur 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/lib/facteur/addressee_model.rb +122 -0
- data/lib/facteur/mailbox_model.rb +12 -0
- data/lib/facteur/message_model.rb +16 -0
- data/lib/facteur.rb +3 -0
- data/spec/db/database.log +0 -0
- data/spec/db/facteur.sqlite3.db +0 -0
- data/spec/facteur_spec.rb +89 -0
- data/spec/spec_helper.rb +67 -0
- metadata +97 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Rawane ZOSSOU
|
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.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= facteur
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Rawane ZOSSOU. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "facteur"
|
8
|
+
gem.summary = "Messages managment system for Rails 3"
|
9
|
+
gem.description = "Facteur allows you add a messages management system in your Rails 3. You can create many mailboxes for your users. They will be able to send and receive messages."
|
10
|
+
gem.email = "dev@raw1z.fr"
|
11
|
+
gem.homepage = "http://github.com/raw1z/facteur"
|
12
|
+
gem.authors = ["Rawane ZOSSOU"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rspec/core'
|
22
|
+
require 'rspec/core/rake_task'
|
23
|
+
Rspec::Core::RakeTask.new(:spec) do |spec|
|
24
|
+
end
|
25
|
+
|
26
|
+
Rspec::Core::RakeTask.new(:rcov) do |spec|
|
27
|
+
end
|
28
|
+
|
29
|
+
task :spec => :check_dependencies
|
30
|
+
|
31
|
+
task :default => :spec
|
32
|
+
|
33
|
+
require 'rake/rdoctask'
|
34
|
+
Rake::RDocTask.new do |rdoc|
|
35
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
36
|
+
|
37
|
+
rdoc.rdoc_dir = 'rdoc'
|
38
|
+
rdoc.title = "facteur #{version}"
|
39
|
+
rdoc.rdoc_files.include('README*')
|
40
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
41
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Facteur
|
2
|
+
module AddresseeModel
|
3
|
+
def self.included(receiver)
|
4
|
+
receiver.class_exec do
|
5
|
+
include InstanceMethods
|
6
|
+
|
7
|
+
has_many :mailboxes, :as => :addressee
|
8
|
+
has_many :messages_sent, :class_name => "Message", :foreign_key => "author_id"
|
9
|
+
|
10
|
+
# the addressee's mailboxes are created after its creation
|
11
|
+
after_create :create_mailboxes
|
12
|
+
end
|
13
|
+
|
14
|
+
receiver.extend ClassMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
|
19
|
+
# Define a mailbox. The following options are available:
|
20
|
+
# <tt>:default</tt>:: defines the default mailbox. You must choose one default mailbox
|
21
|
+
def mailbox(name, options={})
|
22
|
+
mailbox = {:name => name}
|
23
|
+
mailbox.merge! options
|
24
|
+
mailboxes << mailbox
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the mailboxes defined for the class
|
28
|
+
def mailboxes
|
29
|
+
@mailboxes ||= []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module InstanceMethods
|
34
|
+
|
35
|
+
# Sends a message to one or many addressees. The following options are available:
|
36
|
+
#
|
37
|
+
# <tt>:to</tt>:: the addressee or the list of addressees (mandatory)
|
38
|
+
# <tt>:in</tt>:: the name of the mailbox in which the message is posted (mandatory)
|
39
|
+
# <tt>:body</tt>:: the message's body (mandatory)
|
40
|
+
#
|
41
|
+
# Usage :
|
42
|
+
#
|
43
|
+
# # send a message to one addressee
|
44
|
+
# @john.send_message('message contents', :to => @peter, :in => :private_mailbox)
|
45
|
+
#
|
46
|
+
# # send a message to many addressees
|
47
|
+
# @john.send_message('message contents', :to => [@peter, @james], :in => :private_mailbox)
|
48
|
+
def send_message(message, options)
|
49
|
+
options[:body] = message
|
50
|
+
if options[:to].is_a? Array
|
51
|
+
options[:to].each do |addressee|
|
52
|
+
send_message_to(addressee, options[:in], options[:body])
|
53
|
+
end
|
54
|
+
else
|
55
|
+
send_message_to(options[:to], options[:in], options[:body])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Creates a new mailbox. if a mailbox with the same name already exists, it fails and returns false. If succeeded, it creates an accessor for the new mail box and returns true.
|
60
|
+
# Example :
|
61
|
+
#
|
62
|
+
# class User < ActiveRecord::base
|
63
|
+
# include Facteur::AddresseeModel
|
64
|
+
#
|
65
|
+
# mailbox :private_mailbox
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# The previous declaration will add : User#private_mailbox
|
69
|
+
#
|
70
|
+
# # supposing that a name field exists
|
71
|
+
# user = User.new(:name => 'John')
|
72
|
+
# user.create_mailbox :public_mailbox #=> return true
|
73
|
+
# user.create_mailbox :private_mailbox #=> return false
|
74
|
+
def create_mailbox(name, options={})
|
75
|
+
mailbox = Mailbox.new(:name => name.to_s)
|
76
|
+
mailbox.addressee = self
|
77
|
+
return false if mailbox.save == false
|
78
|
+
|
79
|
+
@default_mailbox = name if options[:default]
|
80
|
+
self.class.class_eval do
|
81
|
+
define_method(name) do
|
82
|
+
self.mailboxes.where(:name => name.to_s).first
|
83
|
+
end
|
84
|
+
end
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
# Creates a new mailbox. if a mailbox with the same name already exists, it raises an exception. If succeeded, it creates an accessor for the new mail box and returns the created mailbox.
|
89
|
+
def create_mailbox!(name, options={})
|
90
|
+
if create_mailbox(name, options) == false
|
91
|
+
raise "Mailboxes names must be unique. Can't create '#{name}'"
|
92
|
+
end
|
93
|
+
self.send "#{name}"
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
# creates the mailboxes defined in the configuration
|
99
|
+
def create_mailboxes
|
100
|
+
self.class.mailboxes.each do |mailbox|
|
101
|
+
options = {}.merge(mailbox)
|
102
|
+
name = options.delete(:name)
|
103
|
+
create_mailbox!(name, options)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# send a message to an addressee
|
108
|
+
def send_message_to(addressee, mailbox_name, contents)
|
109
|
+
return false if addressee.nil? or contents.nil?
|
110
|
+
|
111
|
+
mailbox_name = @default_mailbox if mailbox_name.nil?
|
112
|
+
return false if mailbox_name.nil?
|
113
|
+
|
114
|
+
message = Message.new
|
115
|
+
message.author = self
|
116
|
+
message.mailbox = addressee.send(mailbox_name)
|
117
|
+
message.body = contents
|
118
|
+
message.save
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Facteur
|
2
|
+
module MailboxModel
|
3
|
+
def self.included(receiver)
|
4
|
+
receiver.class_exec do
|
5
|
+
belongs_to :addressee, :polymorphic => true
|
6
|
+
has_many :messages
|
7
|
+
validates_presence_of :name
|
8
|
+
validates_uniqueness_of :name, :scope => [:addressee_id, :addressee_type]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Facteur
|
2
|
+
module MessageModel
|
3
|
+
def self.included(receiver)
|
4
|
+
receiver.class_exec do
|
5
|
+
validates_presence_of :author_id, :mailbox_id, :body
|
6
|
+
|
7
|
+
belongs_to :mailbox
|
8
|
+
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
|
9
|
+
|
10
|
+
delegate :addressee, :to => :mailbox
|
11
|
+
delegate :addressee_type, :to => :mailbox
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/lib/facteur.rb
ADDED
File without changes
|
Binary file
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Facteur::AddresseeModel do
|
4
|
+
context "when creating mailboxes" do
|
5
|
+
before(:each) do
|
6
|
+
create_users
|
7
|
+
Message.delete_all
|
8
|
+
end
|
9
|
+
|
10
|
+
it "creates a new mailbox" do
|
11
|
+
@john.create_mailbox(:news_mailbox).should == true
|
12
|
+
|
13
|
+
lambda { @peter.create_mailbox! :news_mailbox }.should_not raise_error
|
14
|
+
|
15
|
+
mailbox = @victoria.create_mailbox! :news_mailbox
|
16
|
+
mailbox.addressee.should == @victoria
|
17
|
+
end
|
18
|
+
|
19
|
+
it "could not create a mailbox with the name of an existing mailbox" do
|
20
|
+
@john.create_mailbox(:private_mailbox).should == false
|
21
|
+
lambda { mailbox = @peter.create_mailbox! :private_mailbox }.should raise_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when initialized" do
|
26
|
+
before(:each) do
|
27
|
+
create_users
|
28
|
+
Message.delete_all
|
29
|
+
end
|
30
|
+
|
31
|
+
it "creates the addressee's mailboxes" do
|
32
|
+
@john.mailboxes.where(:name => 'private_mailbox').first.should_not be_nil
|
33
|
+
@john.mailboxes.where(:name => 'public_mailbox').first.should_not be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "defines the mailboxes accessors" do
|
37
|
+
@john.should respond_to :private_mailbox
|
38
|
+
@john.should respond_to :public_mailbox
|
39
|
+
@john.private_mailbox.should_not be_nil
|
40
|
+
@john.public_mailbox.should_not be_nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when sending message" do
|
45
|
+
before(:each) do
|
46
|
+
create_users
|
47
|
+
Message.delete_all
|
48
|
+
end
|
49
|
+
|
50
|
+
it "sends a message to another addressee" do
|
51
|
+
@john.send_message('message contents', :to => @peter, :in => :private_mailbox).should == true
|
52
|
+
message = @peter.private_mailbox.messages.last
|
53
|
+
message.author.should == @john
|
54
|
+
message.body.should == 'message contents'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "sends the messages in the default mailbox" do
|
58
|
+
@john.send_message('message contents', :to => @peter).should == true
|
59
|
+
message = @peter.private_mailbox.messages.last
|
60
|
+
message.author.should == @john
|
61
|
+
message.body.should == 'message contents'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "could not send a message if the addressee is not given" do
|
65
|
+
@john.send_message('message contents', :in => :private_mailbox).should == false
|
66
|
+
end
|
67
|
+
|
68
|
+
it "raises an error if the mailbox name given is unknown" do
|
69
|
+
lambda{ @john.send_message('message contents', :to => @peter, :in => :unknown_mailbox) }.should raise_error
|
70
|
+
end
|
71
|
+
|
72
|
+
it "sends a message to many addressees" do
|
73
|
+
@john.send_message('message contents', :to => [@peter, @james, @jane], :in => :private_mailbox)
|
74
|
+
|
75
|
+
message = @peter.private_mailbox.messages.last
|
76
|
+
message.author.should == @john
|
77
|
+
message.body.should == 'message contents'
|
78
|
+
|
79
|
+
message = @james.private_mailbox.messages.last
|
80
|
+
message.author.should == @john
|
81
|
+
message.body.should == 'message contents'
|
82
|
+
|
83
|
+
message = @jane.private_mailbox.messages.last
|
84
|
+
message.author.should == @john
|
85
|
+
message.body.should == 'message contents'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'parchemin'
|
4
|
+
require 'rspec/core'
|
5
|
+
require 'rspec/autorun'
|
6
|
+
require 'active_record'
|
7
|
+
require 'logger'
|
8
|
+
require 'facteur'
|
9
|
+
|
10
|
+
SPEC_ROOT = File.dirname(__FILE__)
|
11
|
+
|
12
|
+
ActiveRecord::Base.establish_connection(
|
13
|
+
:adapter => "sqlite3",
|
14
|
+
:database => "#{SPEC_ROOT}/db/facteur.sqlite3.db"
|
15
|
+
)
|
16
|
+
|
17
|
+
ActiveRecord::Migration.verbose = false
|
18
|
+
|
19
|
+
ActiveRecord::Schema.define do
|
20
|
+
create_table :users, :force => true do |t|
|
21
|
+
t.string :name, :null => false
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table :mailboxes, :force => true do |t|
|
25
|
+
t.string :name
|
26
|
+
t.text :contents
|
27
|
+
t.integer :addressee_id
|
28
|
+
t.string :addressee_type
|
29
|
+
t.boolean :default
|
30
|
+
end
|
31
|
+
|
32
|
+
create_table :messages, :force => true do |t|
|
33
|
+
t.string :subject
|
34
|
+
t.text :body
|
35
|
+
t.integer :mailbox_id
|
36
|
+
t.integer :author_id
|
37
|
+
t.boolean :deleted_by_author, :default => false
|
38
|
+
t.datetime :deleted_by_author_at
|
39
|
+
t.boolean :deleted_by_addressee, :default => false
|
40
|
+
t.datetime :deleted_by_addressee_at
|
41
|
+
t.boolean :read, :default => false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
ActiveRecord::Base.logger = Logger.new(File.open("#{SPEC_ROOT}/db/database.log", 'a'))
|
46
|
+
|
47
|
+
class User < ActiveRecord::Base
|
48
|
+
include Facteur::AddresseeModel
|
49
|
+
|
50
|
+
mailbox :private_mailbox, :default => true
|
51
|
+
mailbox :public_mailbox
|
52
|
+
end
|
53
|
+
|
54
|
+
class Mailbox < ActiveRecord::Base
|
55
|
+
include Facteur::MailboxModel
|
56
|
+
end
|
57
|
+
|
58
|
+
class Message < ActiveRecord::Base
|
59
|
+
include Facteur::MessageModel
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_users
|
63
|
+
%w(John Peter James Mary Jane Victoria).each do |name|
|
64
|
+
eval "@#{name.downcase} = User.create(:name => '#{name}')"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: facteur
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Rawane ZOSSOU
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-06-10 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 2
|
33
|
+
- 9
|
34
|
+
version: 1.2.9
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Facteur allows you add a messages management system in your Rails 3. You can create many mailboxes for your users. They will be able to send and receive messages.
|
38
|
+
email: dev@raw1z.fr
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files:
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
files:
|
47
|
+
- .document
|
48
|
+
- .gitignore
|
49
|
+
- LICENSE
|
50
|
+
- README.rdoc
|
51
|
+
- Rakefile
|
52
|
+
- VERSION
|
53
|
+
- lib/facteur.rb
|
54
|
+
- lib/facteur/addressee_model.rb
|
55
|
+
- lib/facteur/mailbox_model.rb
|
56
|
+
- lib/facteur/message_model.rb
|
57
|
+
- spec/db/database.log
|
58
|
+
- spec/db/facteur.sqlite3.db
|
59
|
+
- spec/facteur_spec.rb
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: http://github.com/raw1z/facteur
|
63
|
+
licenses: []
|
64
|
+
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options:
|
67
|
+
- --charset=UTF-8
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 3
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.3.7
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Messages managment system for Rails 3
|
95
|
+
test_files:
|
96
|
+
- spec/facteur_spec.rb
|
97
|
+
- spec/spec_helper.rb
|