inboxes 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.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in inboxes.gemspec
4
+ gemspec
@@ -0,0 +1,60 @@
1
+ #Inboxes
2
+
3
+ Inboxes is a young messaging system for Rails app. It:
4
+
5
+ - provides 3 models for developers: Discussion, Message and Speaker
6
+ - read/unread discussions counter
7
+ - any user can be invited to discussion by the member of this discussion, so you can chat with unlimited number of users
8
+
9
+ ##Requirements and recommendations
10
+
11
+ Inboxes requires Rails 3.x and [Devise](https://github.com/plataformatec/devise) for user identification (surely, messaging system is not possible without users). Now the gem is tested only with Ruby 1.8.7 and REE.
12
+
13
+ We recommend to use Inboxes with [Faye](https://github.com/jcoglan/faye), because it's really sexy with it.
14
+
15
+ Remember that unfortunately, Inboxes reserve 3 resources names: Discussion, Message and Speaker.
16
+
17
+ ##Installation
18
+
19
+ *Make sure that Devise is already installed and configured!*
20
+
21
+ 1. Add `gem "inboxes"` to your `Gemfile` and run `bundle install`
22
+ 2. Execute `rails generate inboxes:install`. This command will generate migration for messaging system. Don't forget to run migrations: `rake db:migrate`
23
+ 3. Add `inboxes` to your User model like [here](https://gist.github.com/1330080)
24
+ 4. Now Inboxes is ready to use. Open `http://yoursite.dev/discussions` to see the list of discussions. You can start new one.
25
+
26
+ Default Inboxes views are ugly, so you can copy into your app and make anything with them: `rails generate inboxes:views`
27
+ If you have problems with installation, you can check [code of demo app](https://github.com/kirs/inboxes-app)
28
+
29
+ ## I18n
30
+
31
+ By default, the gem provides localized phrases for Russian and English languages. You can easily override any of them. [Here is](https://github.com/kirs/inboxes/blob/master/config/locales/en.yml) list of all I18n phrases.
32
+
33
+ #Integration with Faye
34
+
35
+ 1. Add `gem "faye"` to your Gemfile and run `bundle install`. Install Faye by [the screencast](http://railscasts.com/episodes/260-messaging-with-faye)
36
+ 2. Create `messaging.js` in `app/assets/javascripts/` with these lines:
37
+
38
+ /*
39
+ = require inboxes/faye
40
+ */
41
+
42
+ 3. Copy or replace 2 views from Inboxes example app to your application: [app/views/inboxes/messages/_form](https://github.com/kirs/inboxes-app/blob/master/app/views/inboxes/messages/_form.html.haml) and [app/views/inboxes/messages/create](https://github.com/kirs/inboxes-app/blob/master/app/views/inboxes/messages/create.js.erb)
43
+
44
+ 4. Add config parameters to your application config (last 2 are not necessary):
45
+
46
+ config.inboxes.faye_enabled = true
47
+ config.inboxes.faye_host = "inboxes-app.dev" # localhost by default
48
+ config.inboxes.faye_port = 9292 # 9292 by default
49
+
50
+ 5. Faye installation is finished. If you have any troubles, check the [example app](https://github.com/kirs/inboxes-app/)
51
+
52
+ ##Todo
53
+
54
+ - Add RSpec tests
55
+
56
+ ##Authors
57
+
58
+ - [Kir Shatrov](https://github.com/kirs/) (Evrone Company)
59
+
60
+ ##Feel free for pull requests!
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ class Inboxes::BaseController < ApplicationController
2
+
3
+ end
@@ -0,0 +1,67 @@
1
+ class Inboxes::DiscussionsController < Inboxes::BaseController
2
+ before_filter :authenticate_user!
3
+ before_filter :init_and_check_permissions, :only => :show
4
+ before_filter :load_and_check_discussion_recipient, :only => [:create, :new]
5
+
6
+ def index
7
+ @discussions = current_user.discussions
8
+ end
9
+
10
+ # GET /discussions/1
11
+ # GET /discussions/1.json
12
+ def show
13
+ @discussion.mark_as_read_for(current_user)
14
+ end
15
+
16
+ # GET /discussions/new
17
+ # GET /discussions/new.json
18
+ def new
19
+ # @discussion = Discussion.new
20
+ @discussion.messages.build
21
+ end
22
+
23
+ # POST /discussions
24
+ # POST /discussions.json
25
+ def create
26
+ # @discussion = Discussion.new(params[:discussion])
27
+ @discussion.add_recipient_token current_user.id
28
+
29
+ @discussion.messages.each do |m|
30
+ m.discussion = @discussion
31
+ m.user = current_user
32
+ end
33
+
34
+ if @discussion.save
35
+ redirect_to @discussion, :notice => t("inboxes.discussions.started")
36
+ else
37
+ render :action => "new"
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def init_and_check_permissions
44
+ @discussion = Discussion.includes(:messages, :speakers).find(params[:id])
45
+ redirect_to discussions_url, :notice => t("inboxes.discussions.can_not_participate") unless @discussion.can_participate?(current_user)
46
+ end
47
+
48
+ def load_and_check_discussion_recipient
49
+ # initializing model fir new and create actions
50
+ @discussion = Discussion.new((params[:discussion] ? params[:discussion] : {}))
51
+ # @discussion.recipient_tokens = params[:recipients] if params[:recipients] # pre-population
52
+
53
+ # checking if discussion with this user already exists
54
+ if @discussion.recipient_ids && @discussion.recipient_ids.size == 1
55
+ user = User.find(@discussion.recipient_ids.first)
56
+ discussion = Discussion.find_between_users(current_user, user)
57
+ if discussion
58
+ # it exists, let's add message and redirect current user
59
+ @discussion.messages.each do |message|
60
+ Message.create(:discussion => discussion, :user => current_user, :body => message.body) if message.body
61
+ end
62
+ # перекидываем на нее
63
+ redirect_to discussion_url(discussion), :notice => t("inboxes.discussions.exists", :user => user[Inboxes::config.user_name])
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,18 @@
1
+ class Inboxes::MessagesController < Inboxes::BaseController
2
+
3
+ def create
4
+ @discussion = Discussion.find(params[:discussion_id])
5
+ redirect_to root_url, :notice => t("inboxes.discussions.can_not_participate") unless @discussion.can_participate?(current_user)
6
+
7
+ @message = Message.new(params[:message])
8
+ @message.user = current_user
9
+ @message.discussion = @discussion
10
+ @message.save
11
+
12
+ respond_to do |format|
13
+ format.html { redirect_to @message.discussion }
14
+ format.js
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,26 @@
1
+ class Inboxes::SpeakersController < Inboxes::BaseController
2
+ before_filter :init_and_check_permissions
3
+
4
+ def create
5
+ # check permissions
6
+ raise ActiveRecord::RecordNotFound unless params[:speaker] && params[:speaker][:user_id]
7
+ @user = User.find(params[:speaker][:user_id])
8
+
9
+ flash[:notice] = t("views.speakers.added") if @discussion.add_speaker(@user)
10
+ redirect_to @discussion
11
+ end
12
+
13
+ def destroy
14
+ @speaker = Speaker.find(params[:id])
15
+ @speaker.destroy
16
+ flash[:notice] = @speaker.user == current_user ? t("inboxes.discussions.leaved") : t("inboxes.speakers.removed")
17
+ redirect_to @discussion.speakers.any? && @discussion.can_participate?(current_user) ? @discussion : discussions_url
18
+ end
19
+
20
+ private
21
+
22
+ def init_and_check_permissions
23
+ @discussion = Discussion.find(params[:discussion_id])
24
+ redirect_to discussions_url, :notice => t("inboxes.discussions.can_not_participate") unless @discussion.can_participate?(current_user)
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ require 'net/http'
2
+ module InboxesHelper
3
+ def inboxes_faye_broadcast(channel, &block)
4
+ message = {:channel => channel, :data => capture(&block), :ext => {:auth_token => defined?(FAYE_TOKEN) ? FAYE_TOKEN : ""}}
5
+ uri = URI.parse("http://#{Inboxes::config.faye_host}:#{Inboxes::config.faye_port}/faye")
6
+ # Rails.logger.info "Faye URL: #{uri}"
7
+ res = Net::HTTP.post_form(uri, :message => message.to_json)
8
+ end
9
+ end
@@ -0,0 +1,116 @@
1
+
2
+ class Discussion < ActiveRecord::Base
3
+ attr_accessor :recipient_tokens, :recipient_ids
4
+ attr_reader :recipient_ids
5
+
6
+ # paginates_per 10
7
+
8
+ # создатель
9
+ has_many :messages, :dependent => :destroy
10
+
11
+ # участники
12
+ has_many :speakers, :dependent => :destroy
13
+ has_many :users, :through => :speakers
14
+
15
+ # отметки о прочтении юзеров
16
+
17
+ scope :unread_for, (lambda do |user_or_user_id|
18
+ user = user_or_user_id.is_a?(User) ? user_or_user_id.id : user_or_user_id
19
+ joins(:speakers).where("discussions.updated_at >= speakers.updated_at AND speakers.user_id = ?", user)
20
+ end)
21
+
22
+ accepts_nested_attributes_for :messages
23
+
24
+ validate :check_that_has_at_least_two_users # не даем создать дискуссию, у которой нет получателей
25
+
26
+ # добавляем записи об указанных собеседников
27
+ after_save(:on => :create) do
28
+ # Rails.logger.info("Repicients ids: #{recipient_ids.inspect}")
29
+
30
+ if recipient_ids.kind_of?(Array)
31
+ recipient_ids.uniq!
32
+ recipient_ids.each do |id|
33
+ recipient = User.find(id)
34
+ add_speaker(recipient) if recipient
35
+ end
36
+ end
37
+ end
38
+
39
+ def recipient_tokens=(ids)
40
+ self.recipient_ids = ids
41
+ end
42
+
43
+ def add_recipient_token id
44
+ self.recipient_ids << id if self.recipient_ids
45
+ end
46
+
47
+ def add_speaker(user)
48
+ raise ArgumentError, "You can add speaker only to existing Discussion. Save your the Discussion object firstly" if new_record?
49
+ Speaker.create(:discussion => self, :user => user)
50
+ end
51
+
52
+ def remove_speaker(user)
53
+ speaker = find_speaker_by_user(user)
54
+ speaker.destroy if speaker
55
+ end
56
+
57
+ def user_invited_at(user)
58
+ speaker = find_speaker_by_user(user)
59
+ speaker.created_at
60
+ end
61
+
62
+ def can_participate?(user)
63
+ speaker = find_speaker_by_user(user)
64
+ speaker ? true : false
65
+ end
66
+
67
+ # проверяет, есть ли уже беседа между пользователями
68
+ # TODO вынести в отдельный метод а в этом возращать true/false, а то неправославно как-то
69
+ def self.find_between_users(user, user2)
70
+ dialog = nil
71
+ discussions = self.joins(:speakers).includes(:users).where("speakers.user_id = ?", user.id)
72
+ Rails.logger.info "Searching for ids: #{user.id}, #{user2.id}"
73
+ discussions.each do |discussion|
74
+ dialog = discussion if discussion.private? && ((discussion.users.first == user && discussion.users.last == user2) || (discussion.users.first == user2 && discussion.users.last == user))
75
+ end
76
+ dialog
77
+ end
78
+
79
+ # приватная/групповая
80
+ def private?
81
+ self.users.size <= 2
82
+ end
83
+
84
+ # дата последнего сообщения в дискуссии
85
+ # def last_message_at
86
+ # self.messages.last ? self.messages.last.created_at : nil
87
+ # end
88
+
89
+ # проверка, является ли дискуссия непрочитанной для пользователя
90
+ def unread_for?(user)
91
+ speaker = find_speaker_by_user(user)
92
+ if speaker
93
+ self.updated_at >= speaker.updated_at
94
+ else
95
+ true
96
+ end
97
+ end
98
+
99
+ # пометить как прочитанная
100
+ def mark_as_read_for(user)
101
+ speaker = Speaker.find_or_create_by_user_id_and_discussion_id(user.id, self.id)
102
+ # flag.update_attributes(:updat => Time.zone.now)
103
+ speaker.touch
104
+ end
105
+
106
+ def find_speaker_by_user user
107
+ Speaker.find_by_discussion_id_and_user_id(self.id, user.id)
108
+ end
109
+
110
+ private
111
+
112
+ def check_that_has_at_least_two_users
113
+ errors.add :recipient_tokens, t("inboxes.discussions.choose_at_least_one_recipient") if !self.recipient_ids || self.recipient_ids.size < 2
114
+ end
115
+
116
+ end
@@ -0,0 +1,22 @@
1
+ class Message < ActiveRecord::Base
2
+
3
+ default_scope order(:created_at)
4
+
5
+ belongs_to :discussion, :counter_cache => true
6
+ belongs_to :user
7
+
8
+ validates :user, :discussion, :body, :presence => true
9
+
10
+ after_save :touch_discussion_and_mark_as_read
11
+
12
+ def visible_for? user
13
+ self.created_at.to_i >= self.discussion.user_invited_at(user).to_i
14
+ end
15
+
16
+ private
17
+
18
+ def touch_discussion_and_mark_as_read
19
+ self.discussion.touch
20
+ self.discussion.mark_as_read_for(self.user)
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ class Speaker < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :discussion
4
+
5
+ validates_uniqueness_of :user_id, :scope => :discussion_id
6
+ validates :user, :discussion, :presence => true
7
+
8
+ after_destroy :destroy_discussion
9
+
10
+ private
11
+
12
+ def destroy_discussion
13
+ self.discussion.destroy unless self.discussion.speakers.any?
14
+ end
15
+
16
+ end
@@ -0,0 +1,12 @@
1
+ = form_for @discussion do |f|
2
+ %p
3
+ = f.label :recipient_tokens
4
+ %br
5
+ = select_tag "discussion[recipient_tokens]", options_from_collection_for_select(User.all, :id, Inboxes::config.user_name), :multiple => true, :size => "4"
6
+ %p
7
+ = f.fields_for :messages do |j|
8
+ = j.label :body
9
+ %br
10
+ = j.text_area :body
11
+
12
+ %p= f.submit
@@ -0,0 +1,19 @@
1
+ %h1 Discussions list
2
+ %p
3
+ Unread messages:
4
+ %table
5
+ %tr
6
+ %th Last message
7
+ %th Members
8
+ %th Unread
9
+ - @discussions.each do |discussion|
10
+ %tr
11
+ %td
12
+ = discussion.updated_at
13
+ %td
14
+ = link_to discussion.users.collect{|u| u[Inboxes::config.user_name]}.join(', '), discussion
15
+ %td
16
+ = discussion.unread_for?(current_user) ? "Yes" : "No"
17
+
18
+ %p
19
+ = link_to "Create new", new_discussion_path
@@ -0,0 +1,5 @@
1
+ %h1 New discussion
2
+
3
+ = render "form"
4
+
5
+ %p= link_to "All discussions", discussions_path
@@ -0,0 +1,31 @@
1
+ - if Inboxes::config.faye_enabled
2
+ = javascript_include_tag "messaging"
3
+
4
+ %h1 Discussion
5
+
6
+ %h3
7
+ Members
8
+ - @discussion.speakers.each do |speaker|
9
+ %div
10
+ = speaker.user[Inboxes::config.user_name]
11
+ = link_to '(remove)', discussion_speaker_path(@discussion, speaker), :method => :delete
12
+
13
+ - available_users = User.all.map { |u| u unless @discussion.users.include?(u) }.delete_if { |w| w.nil? }
14
+ - if available_users.any?
15
+ = form_for Speaker.new, :url => discussion_speakers_path(@discussion) do |f|
16
+ = f.label :user_id, "Add speaker"
17
+ = f.collection_select :user_id, available_users, :id, :name
18
+ = f.submit "Add"
19
+
20
+
21
+ %h3 Messages
22
+
23
+ #messages_box
24
+ = render @discussion.messages, :as => :message
25
+
26
+ %h3 Add message
27
+ = render "inboxes/messages/form"
28
+
29
+ %p
30
+ = link_to "Leave discussion", discussion_speaker_path(@discussion, @discussion.find_speaker_by_user(current_user)), :method => :delete unless @discussion.private?
31
+ = link_to "All discussions", discussions_path
@@ -0,0 +1,7 @@
1
+ .message_form
2
+ = form_for Message.new, :url => discussion_messages_path(@discussion.id), :method => :post do |f|
3
+ %p
4
+ = f.label :body
5
+ %br
6
+ = f.text_area :body
7
+ %p= f.submit
@@ -0,0 +1,8 @@
1
+ .message
2
+ %p
3
+ %span
4
+ = message.user[Inboxes::config.user_name]
5
+ @
6
+ = l(message.created_at)
7
+ =":"
8
+ %b= message.body
@@ -0,0 +1,15 @@
1
+ en:
2
+ activerecord:
3
+ attributes:
4
+ discussion:
5
+ recipient_tokens: "Recipients"
6
+ inboxes:
7
+ speakers:
8
+ added: "Speaker was added to discussion"
9
+ removed: "Speaker was removed from discussion"
10
+ discussions:
11
+ started: "Discussion started"
12
+ leaved: "You leaved the discussion"
13
+ exists: "Discussion between you and %{user} already exists"
14
+ can_not_participate: "You are not listed in this discussion"
15
+ choose_at_least_one_recipient: "You should choose at least one recipient of discussion"
@@ -0,0 +1,17 @@
1
+ ru:
2
+ activerecord:
3
+ attributes:
4
+ discussion:
5
+ recipient_tokens: "Получатели"
6
+ message:
7
+ body: "Сообщение"
8
+ inboxes:
9
+ discussions:
10
+ started: "Чат начат"
11
+ leaved: "Вы покинули дискуссию"
12
+ exists: "Дискуссия между вами и %{user} уже существует"
13
+ can_not_participate: "Вы не состоите в этой дискуссии"
14
+ choose_at_least_one_recipient: "Укажите хотя бы одного получателя"
15
+ speakers:
16
+ added: "Участник дискуссии добавлен"
17
+ removed: "Участник дискуссии удален"
@@ -0,0 +1,11 @@
1
+ Rails.application.routes.draw do
2
+
3
+ resources :discussions, :except => :edit, :module => :inboxes do
4
+ resources :messages, :only => [:create, :index]
5
+ resources :speakers, :only => [:create, :destroy]
6
+ member do
7
+ post 'leave'
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "inboxes/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "inboxes"
7
+ s.version = Inboxes::VERSION
8
+ s.authors = ["Kir Shatrov"]
9
+ s.email = ["razor.psp@gmail.com"]
10
+ s.homepage = "http://evrone.com/"
11
+ s.summary = %q{Messaging system for Rails 3 app}
12
+ s.description = %q{Messaging system for Rails 3 app}
13
+
14
+ s.rubyforge_project = "inboxes"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "ruby-debug"
23
+ s.add_runtime_dependency "haml-rails"
24
+ # s.add_runtime_dependency "inherited_resources"
25
+
26
+ # s.add_development_dependency 'dm-sqlite-adapter', ['>= 1.1.0']
27
+ s.add_development_dependency 'rspec', ['>= 0']
28
+ s.add_development_dependency 'rspec-rails', ['>= 0']
29
+ # s.add_development_dependency 'rr', ['>= 0']
30
+ # s.add_development_dependency 'steak', ['>= 0']
31
+ # s.add_development_dependency 'capybara', ['>= 0']
32
+ s.add_development_dependency 'database_cleaner', ['>= 0']
33
+ end
@@ -0,0 +1,40 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module Inboxes
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+
9
+ source_root File.expand_path("../templates", __FILE__)
10
+
11
+ # desc "Generates migration for Discussion, Message, Speaker and DiscussionView models"
12
+
13
+ def self.orm
14
+ Rails::Generators.options[:rails][:orm]
15
+ end
16
+
17
+ # def self.source_root
18
+ # File.join(File.dirname(__FILE__), 'templates', (orm.to_s unless orm.class.eql?(String)) )
19
+ # end
20
+
21
+ def self.orm_has_migration?
22
+ [:active_record].include? orm
23
+ end
24
+
25
+ def self.next_migration_number(dirname)
26
+ if ActiveRecord::Base.timestamped_migrations
27
+ migration_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
28
+ migration_number += 1
29
+ migration_number.to_s
30
+ else
31
+ "%.3d" % (current_migration_number(dirname) + 1)
32
+ end
33
+ end
34
+
35
+ def copy_migration
36
+ migration_template 'install.rb', 'db/migrate/install_inboxes.rb'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ class InstallInboxes < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :discussions do |t|
4
+ t.integer :messages_count, :default => 0 # counter cache
5
+ t.timestamps
6
+ end
7
+
8
+ create_table :messages do |t|
9
+ t.references :user
10
+ t.references :discussion
11
+ t.text :body
12
+
13
+ t.timestamps
14
+ end
15
+
16
+ create_table :speakers do |t|
17
+ t.references :user
18
+ t.references :discussion
19
+
20
+ t.timestamps
21
+ end
22
+ end
23
+
24
+ def self.down
25
+ drop_table :speakers
26
+ drop_table :discussions
27
+ drop_table :messages
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ require 'rails/generators'
2
+
3
+ module Inboxes
4
+ module Generators
5
+ class ViewsGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../../../../app/views', __FILE__)
7
+ #class_option :template_engine, :type => :string, :aliases => '-e', :desc => 'Template engine for the views. Available options are "erb" and "haml".'
8
+
9
+ # TODO support of both haml and erb
10
+ def copy_or_fetch
11
+ filename_pattern = File.join self.class.source_root, "*" #/*.html.#{template_engine}"
12
+ Dir.glob(filename_pattern).map {|f| File.basename f}.each do |f|
13
+ directory f.to_s, "app/views/#{f}"
14
+ end
15
+ end
16
+
17
+ # private
18
+
19
+ # def template_engine
20
+ # # options[:template_engine].try(:to_s).try(:downcase) || 'erb'
21
+ # end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ require "inboxes/version"
2
+ require "inboxes/railtie"
3
+ require "inboxes/engine"
4
+ require "inboxes/active_record_extension"
5
+
6
+ module Inboxes
7
+
8
+ def self.configure(&block)
9
+ yield @config ||= Inboxes::Configuration.new
10
+ end
11
+
12
+ # Global settings for Inboxes
13
+ def self.config
14
+ @config
15
+ end
16
+
17
+ # need a Class for 3.0
18
+ class Configuration #:nodoc:
19
+ include ActiveSupport::Configurable
20
+ config_accessor :user_name
21
+ config_accessor :faye_host
22
+ config_accessor :faye_port
23
+ config_accessor :faye_enabled
24
+
25
+ def param_name
26
+ config.param_name.respond_to?(:call) ? config.param_name.call() : config.param_name
27
+ end
28
+ end
29
+
30
+ # adding method inboxes for models
31
+ ActiveRecord::Base.extend(Inboxes::ActiveRecordExtension)
32
+
33
+ end
@@ -0,0 +1,11 @@
1
+ module Inboxes
2
+ module ActiveRecordExtension
3
+ def inboxes(options = {})
4
+ # field = options[:as] || name
5
+ # prefix = options[:prefix] || "with"
6
+
7
+ has_many :speakers, :dependent => :destroy
8
+ has_many :discussions, :through => :speakers
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module Inboxes
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails'
2
+
3
+ module Inboxes
4
+ class Railtie < ::Rails::Railtie
5
+ config.inboxes = ActiveSupport::OrderedOptions.new
6
+
7
+ initializer "inboxes.configure" do |app|
8
+ Inboxes.configure do |config|
9
+ config.user_name = app.config.inboxes[:user_name] || "email"
10
+ config.faye_enabled = app.config.inboxes[:faye_enabled] || false
11
+ config.faye_host = app.config.inboxes[:faye_host] || "localhost"
12
+ config.faye_port = app.config.inboxes[:faye_port] || "9292"
13
+ end
14
+
15
+ # app.config.middleware.insert_before "::Rails::Rack::Logger", "Inboxes::Middleware"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module Inboxes
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ /*
2
+ = require_directory ./faye
3
+ */
@@ -0,0 +1,9 @@
1
+ $ ->
2
+ fayeUrl = window.location.origin + ":9292/faye" # change port for post of your Faye daemon
3
+ fayeJS = fayeUrl + ".js"
4
+ $.getScript(fayeJS, (e)->
5
+ faye = new Faye.Client(fayeUrl)
6
+ faye.subscribe(window.location.pathname, (data)->
7
+ eval(data)
8
+ )
9
+ )
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inboxes
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Kir Shatrov
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-16 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: haml-rails
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rspec
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec-rails
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: database_cleaner
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ type: :development
75
+ version_requirements: *id004
76
+ description: Messaging system for Rails 3 app
77
+ email:
78
+ - razor.psp@gmail.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files: []
84
+
85
+ files:
86
+ - .gitignore
87
+ - Gemfile
88
+ - README.md
89
+ - Rakefile
90
+ - app/controllers/inboxes/base_controller.rb
91
+ - app/controllers/inboxes/discussions_controller.rb
92
+ - app/controllers/inboxes/messages_controller.rb
93
+ - app/controllers/inboxes/speakers_controller.rb
94
+ - app/helpers/inboxes_helper.rb
95
+ - app/models/discussion.rb
96
+ - app/models/message.rb
97
+ - app/models/speaker.rb
98
+ - app/views/inboxes/discussions/_form.html.haml
99
+ - app/views/inboxes/discussions/index.html.haml
100
+ - app/views/inboxes/discussions/new.html.haml
101
+ - app/views/inboxes/discussions/show.html.haml
102
+ - app/views/inboxes/messages/_form.html.haml
103
+ - app/views/inboxes/messages/_message.html.haml
104
+ - config/locales/en.yml
105
+ - config/locales/ru.yml
106
+ - config/routes.rb
107
+ - inboxes.gemspec
108
+ - lib/generators/inboxes/install_generator.rb
109
+ - lib/generators/inboxes/templates/install.rb
110
+ - lib/generators/inboxes/views_generator.rb
111
+ - lib/inboxes.rb
112
+ - lib/inboxes/active_record_extension.rb
113
+ - lib/inboxes/engine.rb
114
+ - lib/inboxes/railtie.rb
115
+ - lib/inboxes/version.rb
116
+ - vendor/assets/javascripts/inboxes/faye.js
117
+ - vendor/assets/javascripts/inboxes/faye/init.js.coffee
118
+ homepage: http://evrone.com/
119
+ licenses: []
120
+
121
+ post_install_message:
122
+ rdoc_options: []
123
+
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ hash: 3
132
+ segments:
133
+ - 0
134
+ version: "0"
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 3
141
+ segments:
142
+ - 0
143
+ version: "0"
144
+ requirements: []
145
+
146
+ rubyforge_project: inboxes
147
+ rubygems_version: 1.8.11
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: Messaging system for Rails 3 app
151
+ test_files: []
152
+