Extract message system to plugin.

This commit is contained in:
Robert Waltemath 2014-03-07 09:51:24 +01:00 committed by wvengen
parent fe0b17cdb0
commit 7556c753d0
45 changed files with 298 additions and 45 deletions

View file

@ -44,6 +44,7 @@ gem 'ruby-units'
# we use the git version of acts_as_versioned, and need to include it in this Gemfile
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git'
gem 'foodsoft_wiki', path: 'lib/foodsoft_wiki'
gem 'foodsoft_messages', path: 'lib/foodsoft_messages'
group :production do
gem 'exception_notification'

View file

@ -41,6 +41,13 @@ GIT
acts_as_versioned (0.6.0)
activerecord (>= 3.0.9)
PATH
remote: lib/foodsoft_messages
specs:
foodsoft_messages (0.0.1)
deface (~> 1.0.0)
rails
PATH
remote: lib/foodsoft_wiki
specs:
@ -120,6 +127,7 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.7.0)
colorize (0.6.0)
commonjs (0.2.7)
connection_pool (1.2.0)
content_for_in_controllers (0.0.2)
@ -132,6 +140,10 @@ GEM
daemons (1.1.9)
database_cleaner (1.2.0)
debug_inspector (0.0.2)
deface (1.0.0)
colorize (>= 0.5.8)
nokogiri (~> 1.6.0)
rails (>= 3.1)
diff-lcs (1.2.5)
diffy (3.0.1)
docile (1.1.3)
@ -397,6 +409,7 @@ DEPENDENCIES
exception_notification
factory_girl_rails (~> 4.0)
faker
foodsoft_messages!
foodsoft_wiki!
haml-rails
i18n-js!

View file

@ -199,14 +199,9 @@ module ApplicationHelper
end
end
# render user presentation linking to default action (write message)
# render user presentation linking to default action (plugins can override this)
def show_user_link(user=@current_user)
if user.nil?
show_user user
else
link_to show_user(user), new_message_path('message[mail_to]' => user.id),
:title => I18n.t('helpers.application.write_message')
end
show_user user
end
end

View file

@ -13,16 +13,6 @@ class Mailer < ActionMailer::Base
sender: FoodsoftConfig[:email_sender],
errors_to: FoodsoftConfig[:email_sender]
# Sends an email copy of the given internal foodsoft message.
def foodsoft_message(message, recipient)
set_foodcoop_scope
@message = message
mail subject: "[#{FoodsoftConfig[:name]}] " + message.subject,
to: recipient.email,
from: "#{show_user(message.sender)} <#{message.sender.email}>"
end
# Sends an email with instructions on how to reset the password.
# Assumes user.setResetPasswordToken has been successfully called already.
def reset_password(user)

View file

@ -3,4 +3,3 @@
%section= render 'shared/group', group: @ordergroup
= link_to t('ui.edit'), edit_admin_ordergroup_path(@ordergroup), class: 'btn'
= link_to t('ui.delete'), [:admin, @ordergroup], :data => {:confirm => t('.confirm')}, :method => :delete, class: 'btn btn-danger'
= link_to t('.send_message'), new_message_path(:message => {:group_id => @ordergroup.id}), class: 'btn'

View file

@ -37,4 +37,3 @@
= link_to t('ui.edit'), edit_admin_user_path(@user), class: 'btn'
= link_to t('ui.delete'), [:admin, @user], :data => {:confirm => t('.confirm', user: @user.first_name)},
:method => :delete, class: 'btn btn-danger'
= link_to t('.send_message'), new_message_path(:message => {:mail_to => @user.id}), class: 'btn'

View file

@ -3,4 +3,3 @@
%section= render 'shared/group', group: @workgroup
= link_to t('ui.edit'), edit_admin_workgroup_path(@workgroup), class: 'btn'
= link_to t('ui.delete'), [:admin, @workgroup], :data => {:confirm => t('.confirm')}, :method => :delete, class: 'btn btn-danger'
= link_to_new_message(message_params: {group_id: @workgroup.id})

View file

@ -15,5 +15,4 @@
%td= ordergroup.name
%td=h ordergroup.users.collect { |u| show_user(u) }.join(", ")
%td= format_date ordergroup.last_order.try(:starts)
%td= link_to_new_message(message_params: {group_id: ordergroup.id})

View file

@ -21,5 +21,4 @@
%td= user.phone if @current_user.role_admin? || user.settings.profile["phone_is_public"]
%td= user.ordergroup_name
%td= user.workgroups.collect(&:name).join(', ')
%td= link_to_new_message(message_params: {mail_to: user.id})

View file

@ -2,6 +2,5 @@
%h3= workgroup.name
= render :partial => 'shared/group', :locals => { :group => workgroup }
= link_to t('.show_tasks'), workgroup_tasks_path(workgroup_id: workgroup), class: 'btn'
= link_to_new_message message_params: {group_id: workgroup.id}
- if workgroup.member?(current_user)
= link_to t('.edit'), edit_foodcoop_workgroup_path(workgroup), class: 'btn'

View file

@ -4,7 +4,6 @@
%li.nav-header= t '.foodcoop'
%li= link_to t('.members'), foodcoop_users_path
%li= link_to t('.tasks'), user_tasks_path
%li= link_to t('.write_message'), new_message_path
- has_ordergroup = !@current_user.ordergroup.nil?
- has_orders_role = @current_user.role_orders?

View file

@ -3,6 +3,9 @@
- content_for(:sidebar) do
= render :partial => 'start_nav'
-# placeholder deface to add content using erb[silent]:contains()
- '<dashboard_top_mark>'
- unless @unaccepted_tasks.empty? && @next_tasks.empty? && @unassigned_tasks.size == 0
%section.row-fluid
- unless @next_tasks.empty?
@ -32,11 +35,8 @@
%h2= t '.ordergroup.title'
= render :partial => "apple_bar", :locals => {:apple_bar => AppleBar.new(current_user.ordergroup)}
- unless Message.public.empty?
%section
%h2= t '.messages.title'
= render 'messages/messages', messages: Message.public.order('created_at DESC').limit(5), pagination: false
%p= link_to t('.messages.view_all'), messages_path
-# placeholder deface to add content using erb[silent]:contains()
- '<dashboard_middle_mark>'
- if current_user.ordergroup
// Ordergroup overview
@ -63,3 +63,6 @@
%td{:style => "color:#{color}; width:5em", :class => "currency"}= number_to_currency(ft.amount)
%br/
%p= link_to t('.my_ordergroup.transactions.view'), my_ordergroup_path
-# placeholder deface to add content using erb[silent]:contains()
- '<dashboard_bottom_mark>'

View file

@ -8,11 +8,6 @@ class UserNotifier
self.send method_name, args
end
def self.message_deliver(args)
message_id = args.first
Message.find(message_id).deliver
end
def self.finished_order(args)
order_id = args.first
Order.find(order_id).group_orders.each do |group_order|

View file

@ -748,10 +748,11 @@ en:
role_suppliers: Suppliers
show_google_maps: Show it on Google maps
sort_by: Sort by %{text}
write_message: Write message
deliveries:
new_invoice: New invoice
show_invoice: Show invoice
messages:
write_message: Write message
orders:
old_price: Old price
option_choose: Choose supplier/stock
@ -896,11 +897,6 @@ en:
feedback:
header: '%{user} wrote at %{date}:'
subject: Feedback from %{email}
foodsoft_message:
footer: |
Reply: %{reply_url}
See message online: %{msg_url}
Messaging options: %{profile_url}
invite:
subject: Invitation to the Foodcoop
text: |
@ -1007,6 +1003,12 @@ en:
sent_on: 'Sent:'
subject: 'Subject:'
title: Show message
messages_mailer:
foodsoft_message:
footer: |
Reply: %{reply_url}
See message online: %{msg_url}
Messaging options: %{profile_url}
model:
delivery:
each_stock_article_must_be_unique: Each stock article must not be listed more than once.

View file

@ -17,7 +17,6 @@ SimpleNavigation::Configuration.run do |navigation|
subnav.item :members, I18n.t('navigation.members'), foodcoop_users_path, id: nil
subnav.item :workgroups, I18n.t('navigation.workgroups'), foodcoop_workgroups_path, id: nil
subnav.item :ordergroups, I18n.t('navigation.ordergroups'), foodcoop_ordergroups_path, id: nil
subnav.item :messages, I18n.t('navigation.messages'), messages_path, id: nil
subnav.item :tasks, I18n.t('navigation.tasks'), tasks_path, id: nil
end

View file

@ -73,8 +73,6 @@ Foodsoft::Application.routes.draw do
end
end
resources :messages, :only => [:index, :show, :new, :create]
namespace :foodcoop do
root :to => 'users#index'

View file

@ -0,0 +1,15 @@
FoodsoftMessages
================
This plugin adds messages to foodsoft. A new 'Messages' menu entry is added below the 'Foodcoops' menu in the navigation bar.
This plugin is enabled by default in foodsoft, so you don't need to do anything
to install it. If you still want to, for example when it has been disabled,
add the following to foodsoft's Gemfile:
```Gemfile
gem 'foodsoft_messages', path: 'lib/foodsoft_messages'
```
This plugin is part of the foodsoft package and uses the GPL-3 license (see
foodsoft's LICENSE for the full license text).

View file

@ -0,0 +1,40 @@
#!/usr/bin/env rake
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
begin
require 'rdoc/task'
rescue LoadError
require 'rdoc/rdoc'
require 'rake/rdoctask'
RDoc::Task = Rake::RDocTask
end
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'FoodsoftMessages'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
Bundler::GemHelper.install_tasks
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end
task :default => :test

View file

@ -17,7 +17,7 @@ class MessagesController < ApplicationController
def create
@message = @current_user.send_messages.new(params[:message])
if @message.save
Resque.enqueue(UserNotifier, FoodsoftConfig.scope, 'message_deliver', @message.id)
Resque.enqueue(MessageNotifier, FoodsoftConfig.scope, 'message_deliver', @message.id)
redirect_to messages_url, :notice => I18n.t('messages.create.notice')
else
render :action => 'new'

View file

@ -17,4 +17,5 @@ module MessagesHelper
link_to(link_text.html_safe, new_message_path(message: messages_params), class: 'btn',
title: I18n.t('helpers.submit.message.create'))
end
end

View file

@ -0,0 +1,11 @@
class MessagesMailer < Mailer
# Sends an email copy of the given internal foodsoft message.
def foodsoft_message(message, recipient)
set_foodcoop_scope
@message = message
mail subject: "[#{FoodsoftConfig[:name]}] " + message.subject,
to: recipient.email,
from: "#{show_user(message.sender)} <#{message.sender.email}>"
end
end

View file

@ -75,7 +75,7 @@ class Message < ActiveRecord::Base
for user in recipients
if user.receive_email?
begin
Mailer.foodsoft_message(self, user).deliver
MessagesMailer.foodsoft_message(self, user).deliver
rescue
Rails.logger.warn "Deliver failed for user \##{user.id}: #{user.email}"
end

View file

@ -0,0 +1,2 @@
/ insert_after 'erb:contains("delete")'
= link_to t('.send_message'), new_message_path(:message => {:group_id => @ordergroup.id}), class: 'btn'

View file

@ -0,0 +1,2 @@
/ insert_after 'erb:contains("delete")'
= link_to t('.send_message'), new_message_path(:message => {:mail_to => @user.id}), class: 'btn'

View file

@ -0,0 +1,2 @@
/ insert_after 'erb:contains("delete")'
= link_to_new_message(message_params: {group_id: @workgroup.id})

View file

@ -0,0 +1,2 @@
/ insert_bottom 'tbody tr'
%td= link_to_new_message(message_params: {group_id: ordergroup.id})

View file

@ -0,0 +1,2 @@
/ insert_bottom 'tbody tr'
%td= link_to_new_message(message_params: {mail_to: user.id})

View file

@ -0,0 +1,2 @@
/ insert_after 'erb:contains("tasks")'
= link_to_new_message message_params: {group_id: workgroup.id}

View file

@ -0,0 +1,2 @@
/ insert_after 'erb:contains("tasks")'
%li= link_to t('.write_message'), new_message_path

View file

@ -0,0 +1,6 @@
/ insert_after 'erb[silent]:contains("<dashboard_middle_mark>")'
- unless Message.public.empty?
%section#messages
%h2= t '.messages.title'
= render 'messages/messages', messages: Message.public.order('created_at DESC').limit(5), pagination: false
%p= link_to t('.messages.view_all'), messages_path

View file

@ -0,0 +1,8 @@
class MessageNotifier < UserNotifier
@queue = :foodsoft_notifier
def self.message_deliver(args)
message_id = args.first
Message.find(message_id).deliver
end
end

View file

@ -0,0 +1,77 @@
en:
activerecord:
attributes:
message:
body: Body
group_id: Group
private: Private
recipient_tokens: Recipients
sent_to_all: Send to all members
subject: Subject
models:
message: Message
admin:
ordergroups:
show:
send_message: Send message
users:
show:
send_message: Send message
helpers:
messages:
write_message: Write message
submit:
message:
create: send message
home:
index:
messages:
title: Newest Messages
view_all: See all messages
start_nav:
write_message: Write message
messages:
create:
notice: Message is saved and will be sent.
index:
new: New message
title: Messages
messages:
reply: Reply
model:
reply_header: ! '%{user} wrote on %{when}:'
reply_indent: ! '> %{line}'
reply_subject: ! 'Re: %{subject}'
new:
list:
desc: ! 'Please send messages to all using the mailing-list: %{list}'
mail: for example with an email to %{email}.
subscribe: You can find more about the mailing-list at %{link}.
subscribe_msg: You may have to subscribe to the mailing-list first.
wiki: Wiki (page Mailing-List)
no_user_found: No user found
search: Search ...
search_user: Search user
title: New message
show:
all_messages: All messages
from: ! 'From:'
reply: Reply
sent_on: ! 'Sent:'
subject: ! 'Subject:'
title: Show message
messages_mailer:
foodsoft_message:
footer: ! 'Reply: %{reply_url}
See message online: %{msg_url}
Messaging options: %{profile_url}
'
navigation:
messages: Messages
simple_form:
hints:
message:
private: Message doesnt show in Foodsoft mail inbox

View file

@ -0,0 +1,5 @@
Rails.application.routes.draw do
scope '/:foodcoop' do
resources :messages, :only => [:index, :show, :new, :create]
end
end

View file

@ -0,0 +1,18 @@
# extracted from 20090120184410_road_to_version_three.rb
class CreateMessages < ActiveRecord::Migration
def self.up
create_table :messages do |t|
t.references :sender
t.text :recipients_ids
t.string :subject, :null => false
t.text :body
t.integer :email_state, :default => 0, :null => false
t.boolean :private, :default => false
t.datetime :created_at
end
end
def self.down
drop_table :messages
end
end

View file

@ -0,0 +1,23 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "foodsoft_messages/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "foodsoft_messages"
s.version = FoodsoftMessages::VERSION
s.authors = ["robwa"]
s.email = ["foodsoft-messages@ini.tiative.net"]
s.homepage = "https://github.com/foodcoops/foodsoft"
s.summary = "Messaging plugin for foodsoft."
s.description = "Adds the ability to exchange messages to foodsoft."
s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"]
s.test_files = Dir["test/**/*"]
s.add_dependency "rails"
s.add_dependency "deface", "~> 1.0.0"
s.add_development_dependency "sqlite3"
end

View file

@ -0,0 +1,6 @@
require "foodsoft_messages/engine"
require "foodsoft_messages/user_link"
require "deface"
module FoodsoftMessages
end

View file

@ -0,0 +1,11 @@
module FoodsoftMessages
class Engine < ::Rails::Engine
def navigation(primary, context)
item = SimpleNavigation::Item.new(primary, :messages, I18n.t('navigation.messages'), context.messages_path)
sub_nav = primary[:foodcoop].sub_navigation
# display right before tasks item
tasks_index = sub_nav.items.index(sub_nav[:tasks])
sub_nav.items.insert(tasks_index, item)
end
end
end

View file

@ -0,0 +1,26 @@
module FoodsoftMessages
module UserLink
def self.included(base) # :nodoc:
base.class_eval do
# modify user presentation link to writing a message for the user
def show_user_link(user=@current_user)
if user.nil?
show_user user
else
link_to show_user(user), new_message_path('message[mail_to]' => user.id),
:title => I18n.t('helpers.messages.write_message')
end
end
end
end
end
end
# modify existing helper
ActiveSupport.on_load(:after_initialize) do
ApplicationHelper.send :include, FoodsoftMessages::UserLink
end

View file

@ -0,0 +1,3 @@
module FoodsoftMessages
VERSION = "0.0.1"
end