Commit 3ce46bb6b85c5c1b001c3ee576b557255c40564b
Exists in
master
and in
20 other branches
Merge branch 'noosfero' into rails4
Showing
46 changed files
with
2126 additions
and
45 deletions
Show diff stats
.travis.yml
app/mailers/mailing.rb
1 | -require 'mailing_job' | 1 | +require_dependency 'mailing_job' |
2 | 2 | ||
3 | class Mailing < ActiveRecord::Base | 3 | class Mailing < ActiveRecord::Base |
4 | 4 | ||
@@ -40,10 +40,8 @@ class Mailing < ActiveRecord::Base | @@ -40,10 +40,8 @@ class Mailing < ActiveRecord::Base | ||
40 | begin | 40 | begin |
41 | Mailing::Sender.notification(self, recipient.email).deliver | 41 | Mailing::Sender.notification(self, recipient.email).deliver |
42 | self.mailing_sents.create(:person => recipient) | 42 | self.mailing_sents.create(:person => recipient) |
43 | - rescue Exception | ||
44 | - # FIXME should not discard errors silently. An idea is to collect all | ||
45 | - # errors and generate a task (notification) for the +source+ | ||
46 | - # (environment/organization) listing these errors. | 43 | + rescue Exception => ex |
44 | + Rails.logger.error("#{ex.class.to_s} - #{ex.to_s} at #{__FILE__}:#{__LINE__}") | ||
47 | end | 45 | end |
48 | end | 46 | end |
49 | end | 47 | end |
app/models/add_friend.rb
@@ -14,8 +14,8 @@ class AddFriend < Task | @@ -14,8 +14,8 @@ class AddFriend < Task | ||
14 | alias :friend :target | 14 | alias :friend :target |
15 | alias :friend= :target= | 15 | alias :friend= :target= |
16 | 16 | ||
17 | - validates :requestor, :kind_of => { :kind => Person } | ||
18 | - validates :target, :kind_of => { :kind => Person } | 17 | + validates :requestor, :kind_of => { :kind => Person } |
18 | + validates :target, :kind_of => { :kind => Person } | ||
19 | 19 | ||
20 | after_create do |task| | 20 | after_create do |task| |
21 | TaskMailer.invitation_notification(task).deliver unless task.friend | 21 | TaskMailer.invitation_notification(task).deliver unless task.friend |
app/models/community.rb
1 | class Community < Organization | 1 | class Community < Organization |
2 | 2 | ||
3 | - attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type, :address_reference, :district, :tag_list, :language | 3 | + attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type |
4 | + attr_accessible :address_reference, :district, :tag_list, :language, :description | ||
4 | after_destroy :check_invite_member_for_destroy | 5 | after_destroy :check_invite_member_for_destroy |
5 | 6 | ||
6 | def self.type_name | 7 | def self.type_name |
app/models/create_community.rb
@@ -9,11 +9,15 @@ class CreateCommunity < Task | @@ -9,11 +9,15 @@ class CreateCommunity < Task | ||
9 | alias :environment :target | 9 | alias :environment :target |
10 | alias :environment= :target= | 10 | alias :environment= :target= |
11 | 11 | ||
12 | + attr_accessible :environment, :requestor, :target | ||
13 | + attr_accessible :reject_explanation, :template_id | ||
14 | + | ||
12 | acts_as_having_image | 15 | acts_as_having_image |
13 | 16 | ||
14 | - DATA_FIELDS = Community.fields + ['name', 'closed'] | 17 | + DATA_FIELDS = Community.fields + ['name', 'closed', 'description'] |
15 | DATA_FIELDS.each do |field| | 18 | DATA_FIELDS.each do |field| |
16 | settings_items field.to_sym | 19 | settings_items field.to_sym |
20 | + attr_accessible field.to_sym | ||
17 | end | 21 | end |
18 | 22 | ||
19 | def validate | 23 | def validate |
app/models/event.rb
@@ -114,7 +114,7 @@ class Event < Article | @@ -114,7 +114,7 @@ class Event < Article | ||
114 | end | 114 | end |
115 | 115 | ||
116 | alias_method :article_lead, :lead | 116 | alias_method :article_lead, :lead |
117 | - def lead | 117 | + def lead(length = nil) |
118 | self.class.action_view.render 'content_viewer/event_lead', event: self | 118 | self.class.action_view.render 'content_viewer/event_lead', event: self |
119 | end | 119 | end |
120 | 120 |
app/models/textile_article.rb
@@ -12,7 +12,7 @@ class TextileArticle < TextArticle | @@ -12,7 +12,7 @@ class TextileArticle < TextArticle | ||
12 | convert_to_html(body) | 12 | convert_to_html(body) |
13 | end | 13 | end |
14 | 14 | ||
15 | - def lead | 15 | + def lead(length = nil) |
16 | if abstract.blank? | 16 | if abstract.blank? |
17 | super | 17 | super |
18 | else | 18 | else |
app/views/mailing/sender/notification.html.erb
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | <head> | 3 | <head> |
4 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | 4 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
5 | </head> | 5 | </head> |
6 | - <body> | 6 | + <body style="margin: 0"> |
7 | <%= word_wrap(@message) %> | 7 | <%= word_wrap(@message) %> |
8 | <p> | 8 | <p> |
9 | --<br/> | 9 | --<br/> |
config/schedule.rb
@@ -28,3 +28,15 @@ end | @@ -28,3 +28,15 @@ end | ||
28 | every 30.days do | 28 | every 30.days do |
29 | runner "ProfileSuggestion.generate_all_profile_suggestions" | 29 | runner "ProfileSuggestion.generate_all_profile_suggestions" |
30 | end | 30 | end |
31 | + | ||
32 | +# Loads "schedule.rb" files from plugins | ||
33 | +# | ||
34 | +# Allows Noosfero's plugins schedule jobs using `whenever` Ruby gem the same | ||
35 | +# way we do here, just create the file "config/schedule.rb" into the plugin | ||
36 | +# root directory and write jobs using the same syntax used here (see example in | ||
37 | +# the `newsletter` plugin) | ||
38 | + | ||
39 | +Dir.glob("config/plugins/*/config/schedule.rb").each do |filename| | ||
40 | + filecontent = IO.read(filename) | ||
41 | + instance_eval(Whenever::NumericSeconds.process_string(filecontent), filename) | ||
42 | +end |
features/create_community.feature
@@ -39,44 +39,47 @@ Feature: create community | @@ -39,44 +39,47 @@ Feature: create community | ||
39 | Then I should see "Creating new community" | 39 | Then I should see "Creating new community" |
40 | 40 | ||
41 | Scenario: environment admin receive a task when a user creates a community | 41 | Scenario: environment admin receive a task when a user creates a community |
42 | - Given I am logged in as admin | 42 | + Given I am logged in as "joaosilva" |
43 | And feature "admin_must_approve_new_communities" is enabled on environment | 43 | And feature "admin_must_approve_new_communities" is enabled on environment |
44 | - When I create community "Community for approval" | 44 | + Given "joaosilva" creates the community "Community for approval" |
45 | + Given I am logged in as admin | ||
45 | And I go to admin_user's control panel | 46 | And I go to admin_user's control panel |
46 | - Then I should see "admin_user wants to create community Community for approval" | 47 | + Then I should see "Joao Silva wants to create community Community for approval" |
47 | 48 | ||
48 | Scenario: environment admin accepts new community task | 49 | Scenario: environment admin accepts new community task |
49 | - Given I am logged in as admin | 50 | + Given I am logged in as "joaosilva" |
50 | And feature "admin_must_approve_new_communities" is enabled on environment | 51 | And feature "admin_must_approve_new_communities" is enabled on environment |
51 | - When I create community "Community for approval" | 52 | + Given "joaosilva" creates the community "Community for approval" |
53 | + Given I am logged in as admin | ||
52 | And I go to admin_user's control panel | 54 | And I go to admin_user's control panel |
53 | And I follow "Process requests" | 55 | And I follow "Process requests" |
54 | - And I should see "admin_user wants to create community Community for approval" | 56 | + And I should see "Joao Silva wants to create community Community for approval" |
55 | And I choose "Accept" | 57 | And I choose "Accept" |
56 | When I press "Apply!" | 58 | When I press "Apply!" |
57 | - Then I should not see "admin_user wants to create community Community for approval" | ||
58 | - And I go to admin_user's control panel | 59 | + Then I should not see "Joao Silva wants to create community Community for approval" |
60 | + And I go to joaosilva's control panel | ||
59 | And I follow "Manage my groups" | 61 | And I follow "Manage my groups" |
60 | Then I should see "Community for approval" | 62 | Then I should see "Community for approval" |
61 | 63 | ||
62 | Scenario: environment admin rejects new community task | 64 | Scenario: environment admin rejects new community task |
63 | - Given I am logged in as admin | 65 | + Given I am logged in as "joaosilva" |
64 | And feature "admin_must_approve_new_communities" is enabled on environment | 66 | And feature "admin_must_approve_new_communities" is enabled on environment |
65 | - When I create community "Community for approval" | 67 | + Given "joaosilva" creates the community "Community for approval" |
68 | + Given I am logged in as admin | ||
66 | And I go to admin_user's control panel | 69 | And I go to admin_user's control panel |
67 | And I follow "Process requests" | 70 | And I follow "Process requests" |
68 | - And I should see "admin_user wants to create community Community for approval" | 71 | + And I should see "Joao Silva wants to create community Community for approval" |
69 | And I choose "Reject" | 72 | And I choose "Reject" |
70 | When I press "Apply!" | 73 | When I press "Apply!" |
71 | - Then I should not see "admin_user wants to create community Community for approval" | ||
72 | - And I go to admin_user's control panel | 74 | + Then I should not see "Joao Silva wants to create community Community for approval" |
75 | + And I go to joaosilva's control panel | ||
73 | And I follow "Manage my groups" | 76 | And I follow "Manage my groups" |
74 | Then I should not see "Community for approval" | 77 | Then I should not see "Community for approval" |
75 | 78 | ||
76 | Scenario: new community is listed after approval | 79 | Scenario: new community is listed after approval |
77 | Given I am logged in as admin | 80 | Given I am logged in as admin |
78 | And feature "admin_must_approve_new_communities" is enabled on environment | 81 | And feature "admin_must_approve_new_communities" is enabled on environment |
79 | - When I create community "Community for approval" | 82 | + Given "admin_user" creates the community "Community for approval" |
80 | And I approve community "Community for approval" | 83 | And I approve community "Community for approval" |
81 | And I go to admin_user's control panel | 84 | And I go to admin_user's control panel |
82 | And I follow "Manage my groups" | 85 | And I follow "Manage my groups" |
@@ -85,8 +88,9 @@ Feature: create community | @@ -85,8 +88,9 @@ Feature: create community | ||
85 | Scenario: new community is not listed after rejection | 88 | Scenario: new community is not listed after rejection |
86 | Given I am logged in as admin | 89 | Given I am logged in as admin |
87 | And feature "admin_must_approve_new_communities" is enabled on environment | 90 | And feature "admin_must_approve_new_communities" is enabled on environment |
88 | - When I create community "Community for approval" | 91 | + Given "admin_user" creates the community "Community for approval" |
89 | And I reject community "Community for approval" | 92 | And I reject community "Community for approval" |
90 | And I go to admin_user's control panel | 93 | And I go to admin_user's control panel |
91 | And I follow "Manage my groups" | 94 | And I follow "Manage my groups" |
92 | Then I should not see "Community for approval" | 95 | Then I should not see "Community for approval" |
96 | + |
features/step_definitions/create_community_steps.rb
@@ -8,6 +8,14 @@ Given /^I create community "(.+)"$/ do |community| | @@ -8,6 +8,14 @@ Given /^I create community "(.+)"$/ do |community| | ||
8 | click_button("Create") | 8 | click_button("Create") |
9 | end | 9 | end |
10 | 10 | ||
11 | +Given /^"(.+)" creates the community "(.+)"$/ do |username, community| | ||
12 | + When %{I go to #{username}'s control panel} | ||
13 | + click_link('Manage my groups') | ||
14 | + click_link('Create a new community') | ||
15 | + fill_in("Name", :with => community) | ||
16 | + click_button("Create") | ||
17 | +end | ||
18 | + | ||
11 | Given /^I approve community "(.+)"$/ do |community| | 19 | Given /^I approve community "(.+)"$/ do |community| |
12 | task = CreateCommunity.all.select {|c| c.name == community}.first | 20 | task = CreateCommunity.all.select {|c| c.name == community}.first |
13 | step %{I go to admin_user's control panel} | 21 | step %{I go to admin_user's control panel} |
lib/acts_as_having_image.rb
@@ -5,7 +5,8 @@ module ActsAsHavingImage | @@ -5,7 +5,8 @@ module ActsAsHavingImage | ||
5 | belongs_to :image, dependent: :destroy | 5 | belongs_to :image, dependent: :destroy |
6 | scope :with_image, -> { where "#{table_name}.image_id IS NOT NULL" } | 6 | scope :with_image, -> { where "#{table_name}.image_id IS NOT NULL" } |
7 | scope :without_image, -> { where "#{table_name}.image_id IS NULL" } | 7 | scope :without_image, -> { where "#{table_name}.image_id IS NULL" } |
8 | - self.send(:include, ActsAsHavingImage) | 8 | + attr_accessible :image_builder |
9 | + include ActsAsHavingImage | ||
9 | end | 10 | end |
10 | end | 11 | end |
11 | 12 |
plugins/newsletter/controllers/newsletter_plugin_admin_controller.rb
0 → 100644
@@ -0,0 +1,48 @@ | @@ -0,0 +1,48 @@ | ||
1 | +class NewsletterPluginAdminController < PluginAdminController | ||
2 | + | ||
3 | + def index | ||
4 | + @newsletter = NewsletterPlugin::Newsletter.where(environment_id: environment.id).first_or_initialize | ||
5 | + | ||
6 | + if request.post? | ||
7 | + # token input gives the param as a comma separated string | ||
8 | + params[:newsletter][:blog_ids] = (params[:newsletter][:blog_ids] || '').split(',') | ||
9 | + | ||
10 | + params[:newsletter][:person_id] = user.id | ||
11 | + | ||
12 | + file = params[:file] | ||
13 | + if file && file[:recipients].present? | ||
14 | + @newsletter.import_recipients(file[:recipients], file[:name], file[:email], file[:headers].present?) | ||
15 | + end | ||
16 | + | ||
17 | + if !@newsletter.errors.any? && @newsletter.update_attributes(params[:newsletter]) | ||
18 | + if params['visualize'] | ||
19 | + @message = @newsletter.body | ||
20 | + render :file => 'mailing/sender/notification', :layout => false | ||
21 | + else | ||
22 | + session[:notice] = _('Newsletter updated.') | ||
23 | + end | ||
24 | + else | ||
25 | + session[:notice] = _('Newsletter could not be saved.') | ||
26 | + end | ||
27 | + end | ||
28 | + | ||
29 | + @blogs = Blog.includes(:profile).find_all_by_id(@newsletter.blog_ids) | ||
30 | + end | ||
31 | + | ||
32 | + #TODO: Make this query faster | ||
33 | + def search_communities | ||
34 | + communities = environment.communities | ||
35 | + blogs = Blog.joins(:profile).where(profiles: {environment_id: environment.id}) | ||
36 | + | ||
37 | + found_communities = find_by_contents(:communities, environment, communities, params['q'], {:page => 1})[:results] | ||
38 | + found_blogs = find_by_contents(:blogs, environment, blogs, params['q'], {:page => 1})[:results] | ||
39 | + | ||
40 | + results = (found_blogs + found_communities.map(&:blogs).flatten).uniq | ||
41 | + render :text => results.map { |blog| {:id => blog.id, :name => _("%s in %s") % [blog.name, blog.profile.name]} }.to_json | ||
42 | + end | ||
43 | + | ||
44 | + def recipients | ||
45 | + @additional_recipients = NewsletterPlugin::Newsletter.where(environment_id: environment.id).first_or_initialize.additional_recipients | ||
46 | + end | ||
47 | + | ||
48 | +end |
plugins/newsletter/controllers/newsletter_plugin_controller.rb
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +class NewsletterPluginController < PublicController | ||
2 | + | ||
3 | + before_filter :login_required, :only => :confirm_unsubscription | ||
4 | + | ||
5 | + def mailing | ||
6 | + if NewsletterPlugin::NewsletterMailing.exists?(params[:id]) | ||
7 | + mailing = NewsletterPlugin::NewsletterMailing.find(params[:id]) | ||
8 | + @message = mailing.body | ||
9 | + render :file => 'mailing/sender/notification', :layout => false | ||
10 | + else | ||
11 | + render :action => 'mailing_not_found' | ||
12 | + end | ||
13 | + end | ||
14 | + | ||
15 | + def confirm_unsubscription | ||
16 | + if request.post? | ||
17 | + session[:notice] = _('You was unsubscribed from newsletter.') | ||
18 | + @newsletter = NewsletterPlugin::Newsletter.where(environment_id: environment.id).first | ||
19 | + @newsletter.unsubscribe(current_user.email) | ||
20 | + redirect_to :controller => :home | ||
21 | + end | ||
22 | + end | ||
23 | + | ||
24 | +end |
plugins/newsletter/db/migrate/20150717195546_newsletter_plugin_newsletters.rb
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +class NewsletterPluginNewsletters < ActiveRecord::Migration | ||
2 | + def up | ||
3 | + create_table :newsletter_plugin_newsletters do |t| | ||
4 | + t.references :environment, :null => false | ||
5 | + t.references :person, :null => false | ||
6 | + t.boolean :enabled, :default => false | ||
7 | + t.string :subject | ||
8 | + t.integer :periodicity, :default => 0 | ||
9 | + t.integer :posts_per_blog, :default => 0 | ||
10 | + t.integer :image_id | ||
11 | + t.text :footer | ||
12 | + t.text :blog_ids | ||
13 | + t.text :additional_recipients | ||
14 | + t.boolean :moderated | ||
15 | + t.text :unsubscribers | ||
16 | + end | ||
17 | + add_index :newsletter_plugin_newsletters, :environment_id, :uniq => true | ||
18 | + end | ||
19 | + | ||
20 | + def down | ||
21 | + remove_index :newsletter_plugin_newsletters, :environment_id | ||
22 | + drop_table :newsletter_plugin_newsletters | ||
23 | + end | ||
24 | +end |
@@ -0,0 +1,40 @@ | @@ -0,0 +1,40 @@ | ||
1 | +Feature: newsletter plugin | ||
2 | + | ||
3 | + Background: | ||
4 | + Given the following users | ||
5 | + | login | name | | ||
6 | + | joaosilva | Joao Silva | | ||
7 | + And I am logged in as "joaosilva" | ||
8 | + | ||
9 | + Scenario: as admin I can configure plugin | ||
10 | + Given I am logged in as admin | ||
11 | + When I go to the environment control panel | ||
12 | + And I follow "Plugins" | ||
13 | + Then I should see "Configuration" linking to "/admin/plugin/newsletter" | ||
14 | + | ||
15 | + Scenario: in the newsletter settings I can see the field to enable/disable | ||
16 | + Given I am logged in as admin | ||
17 | + When I go to the environment control panel | ||
18 | + And I follow "Plugins" | ||
19 | + And I follow "Configuration" | ||
20 | + Then I should see "Enable send of newsletter to members on this environment" | ||
21 | + | ||
22 | + Scenario: redirect to newsletter visualization after save and visualize | ||
23 | + Given I am logged in as admin | ||
24 | + And "NewsletterPlugin" plugin is enabled | ||
25 | + When I go to the environment control panel | ||
26 | + And I follow "Plugins" | ||
27 | + And I follow "Configuration" | ||
28 | + And I press "Save and visualize" | ||
29 | + Then I should see "If you can't view this email, click here" | ||
30 | + And I should not see "Newsletter settings" | ||
31 | + | ||
32 | + Scenario: stay on newsletter settings page after save | ||
33 | + Given I am logged in as admin | ||
34 | + And "NewsletterPlugin" plugin is enabled | ||
35 | + When I go to the environment control panel | ||
36 | + And I follow "Plugins" | ||
37 | + And I follow "Configuration" | ||
38 | + And I press "Save" | ||
39 | + Then I should see "Newsletter settings" | ||
40 | + And I should not see "If you can't view this email, click here" |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +class NewsletterPlugin < Noosfero::Plugin | ||
2 | + | ||
3 | + def self.plugin_name | ||
4 | + "Newsletter" | ||
5 | + end | ||
6 | + | ||
7 | + def self.plugin_description | ||
8 | + _("Periodically sends newsletter via email to network users") | ||
9 | + end | ||
10 | + | ||
11 | + def js_files | ||
12 | + 'newsletter_plugin.js' | ||
13 | + end | ||
14 | + | ||
15 | + def stylesheet? | ||
16 | + true | ||
17 | + end | ||
18 | + | ||
19 | + def self.compile_and_send_newsletters | ||
20 | + NewsletterPlugin::Newsletter.enabled.each do |newsletter| | ||
21 | + if newsletter.must_be_sent_today? && newsletter.has_posts_in_the_period? | ||
22 | + if newsletter.moderated | ||
23 | + NewsletterPlugin::ModerateNewsletter.create!( | ||
24 | + :newsletter_id => newsletter.id, | ||
25 | + :environment => newsletter.environment | ||
26 | + ) | ||
27 | + else | ||
28 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | ||
29 | + :source => newsletter, | ||
30 | + :subject => newsletter.subject, | ||
31 | + :body => newsletter.body, | ||
32 | + :person => newsletter.person, | ||
33 | + :locale => newsletter.environment.default_locale, | ||
34 | + ) | ||
35 | + mailing.update_attribute(:body, mailing.body.gsub('{mailing_url}', mailing.url)) | ||
36 | + end | ||
37 | + end | ||
38 | + end | ||
39 | + end | ||
40 | + | ||
41 | +end |
plugins/newsletter/lib/newsletter_plugin/moderate_newsletter.rb
0 → 100644
@@ -0,0 +1,53 @@ | @@ -0,0 +1,53 @@ | ||
1 | +class NewsletterPlugin::ModerateNewsletter < Task | ||
2 | + | ||
3 | + settings_items :newsletter_id, :post_ids | ||
4 | + validates_presence_of :newsletter_id | ||
5 | + | ||
6 | + alias :environment :target | ||
7 | + alias :environment= :target= | ||
8 | + | ||
9 | + def perform | ||
10 | + newsletter = NewsletterPlugin::Newsletter.find(newsletter_id) | ||
11 | + self.post_ids ||= [] | ||
12 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | ||
13 | + :source => newsletter, | ||
14 | + :subject => newsletter.subject, | ||
15 | + :body => newsletter.body(:post_ids => self.post_ids.reject{|id| id.to_i.zero?}), | ||
16 | + :person => newsletter.person, | ||
17 | + :locale => newsletter.environment.default_locale, | ||
18 | + ) | ||
19 | + mailing.update_attribute(:body, mailing.body.gsub('{mailing_url}', mailing.url)) | ||
20 | + end | ||
21 | + | ||
22 | + def title | ||
23 | + _("Moderate newsletter") | ||
24 | + end | ||
25 | + | ||
26 | + def subject | ||
27 | + nil | ||
28 | + end | ||
29 | + | ||
30 | + def linked_subject | ||
31 | + nil | ||
32 | + end | ||
33 | + | ||
34 | + def information | ||
35 | + {:message => _('You have to moderate a newsletter.') } | ||
36 | + end | ||
37 | + | ||
38 | + def accept_details | ||
39 | + true | ||
40 | + end | ||
41 | + | ||
42 | + def icon | ||
43 | + {:type => :defined_image, :src => "/images/control-panel/email.png", :name => 'Newsletter'} | ||
44 | + end | ||
45 | + | ||
46 | + def target_notification_message | ||
47 | + _('A newsletter was generated and you need to review it before it is sent to users.') | ||
48 | + end | ||
49 | + | ||
50 | + def target_notification_description | ||
51 | + _('You need to moderate a newsletter.') | ||
52 | + end | ||
53 | +end |
@@ -0,0 +1,191 @@ | @@ -0,0 +1,191 @@ | ||
1 | +require 'csv' | ||
2 | + | ||
3 | +class NewsletterPlugin::Newsletter < Noosfero::Plugin::ActiveRecord | ||
4 | + | ||
5 | + belongs_to :environment | ||
6 | + belongs_to :person | ||
7 | + validates_presence_of :environment, :person | ||
8 | + validates_uniqueness_of :environment_id | ||
9 | + validates_numericality_of :periodicity, only_integer: true, greater_than: -1, message: _('must be a positive number') | ||
10 | + validates_numericality_of :posts_per_blog, only_integer: true, greater_than: -1, message: _('must be a positive number') | ||
11 | + | ||
12 | + attr_accessible :environment, :enabled, :periodicity, :subject, :posts_per_blog, :footer, :blog_ids, :additional_recipients, :person, :person_id, :moderated | ||
13 | + | ||
14 | + scope :enabled, :conditions => { :enabled => true } | ||
15 | + | ||
16 | + # These methods are used by NewsletterMailing | ||
17 | + def people | ||
18 | + list = unsubscribers.map{|i| "'#{i}'"}.join(',') | ||
19 | + if list.empty? | ||
20 | + environment.people | ||
21 | + else | ||
22 | + environment.people.all( | ||
23 | + :joins => "LEFT OUTER JOIN users ON (users.id = profiles.user_id)", | ||
24 | + :conditions => "users.email NOT IN (#{list})" | ||
25 | + ) | ||
26 | + end | ||
27 | + end | ||
28 | + | ||
29 | + def name | ||
30 | + environment.name | ||
31 | + end | ||
32 | + | ||
33 | + def contact_email | ||
34 | + environment.noreply_email | ||
35 | + end | ||
36 | + | ||
37 | + def top_url | ||
38 | + environment.top_url | ||
39 | + end | ||
40 | + | ||
41 | + def unsubscribe_url | ||
42 | + "#{top_url}/plugin/newsletter/unsubscribe" | ||
43 | + end | ||
44 | + | ||
45 | + serialize :blog_ids, Array | ||
46 | + serialize :additional_recipients, Array | ||
47 | + | ||
48 | + def blog_ids | ||
49 | + self[:blog_ids].map(&:to_i) || [] | ||
50 | + end | ||
51 | + | ||
52 | + validates_each :blog_ids do |record, attr, value| | ||
53 | + if record.environment | ||
54 | + unless value.delete_if(&:zero?).select { |id| !Blog.find_by_id(id) || Blog.find(id).environment != record.environment }.empty? | ||
55 | + record.errors.add(attr, _('must be valid')) | ||
56 | + end | ||
57 | + end | ||
58 | + unless value.uniq.length == value.length | ||
59 | + record.errors.add(attr, _('must not have duplicates')) | ||
60 | + end | ||
61 | + end | ||
62 | + | ||
63 | + validates_each :additional_recipients do |record, attr, value| | ||
64 | + unless value.reject { |recipient| recipient[:email] =~ Noosfero::Constants::EMAIL_FORMAT }.empty? | ||
65 | + record.errors.add(attr, _('must have only valid emails')) | ||
66 | + end | ||
67 | + end | ||
68 | + | ||
69 | + def next_send_at | ||
70 | + (self.last_send_at || DateTime.now) + self.periodicity.days | ||
71 | + end | ||
72 | + | ||
73 | + def must_be_sent_today? | ||
74 | + return true unless self.last_send_at | ||
75 | + Date.today >= self.next_send_at.to_date | ||
76 | + end | ||
77 | + | ||
78 | + def blogs | ||
79 | + Blog.where(:id => blog_ids) | ||
80 | + end | ||
81 | + | ||
82 | + def posts(data = {}) | ||
83 | + limit = self.posts_per_blog.zero? ? nil : self.posts_per_blog | ||
84 | + posts = if self.last_send_at.nil? | ||
85 | + self.blogs.map{|blog| blog.posts.all(:limit => limit)}.flatten | ||
86 | + else | ||
87 | + self.blogs.map{|blog| blog.posts.where("published_at >= :last_send_at", {last_send_at: self.last_send_at}).all(:limit => limit)}.flatten | ||
88 | + end | ||
89 | + data[:post_ids].nil? ? posts : posts.select{|post| data[:post_ids].include?(post.id.to_s)} | ||
90 | + end | ||
91 | + | ||
92 | + CSS = { | ||
93 | + 'breakingnews-wrap' => 'background-color: #EFEFEF; padding: 40px 0', | ||
94 | + 'breakingnews' => 'width: 640px; margin: auto; background-color: white; border: 1px solid #ddd; border-spacing: 0; padding: 0', | ||
95 | + 'newsletter-public-link' => 'width: 640px; margin: auto; font-size: small; color: #555; font-style: italic; text-align: right; margin-bottom: 15px; font-family: sans;', | ||
96 | + 'newsletter-header' => 'padding: 0', | ||
97 | + 'header-image' => 'width: 100%', | ||
98 | + 'post-image' => 'padding-left: 20px; width: 25%; border-bottom: 1px dashed #DDD', | ||
99 | + 'post-info' => 'font-family: Arial, Verdana; padding: 20px; width: 75%; border-bottom: 1px dashed #DDD', | ||
100 | + 'post-date' => 'font-size: 12px;', | ||
101 | + 'post-lead' => 'font-size: 14px; text-align: justify', | ||
102 | + 'post-title' => 'color: #000; text-decoration: none; font-size: 16px; text-align: justify', | ||
103 | + 'read-more-line' => 'text-align: right', | ||
104 | + 'read-more-link' => 'color: #000; font-size: 12px;', | ||
105 | + 'newsletter-unsubscribe' => 'width: 640px; margin: auto; font-size: small; color: #555; font-style: italic; text-align: center; margin-top: 15px; font-family: sans;' | ||
106 | + } | ||
107 | + | ||
108 | + # to be able to generate HTML | ||
109 | + include ActionView::Helpers | ||
110 | + include Rails.application.routes.url_helpers | ||
111 | + include DatesHelper | ||
112 | + | ||
113 | + def message_to_public_link | ||
114 | + content_tag(:p, N_("If you can't view this email, %s.") % link_to(N_('click here'), '{mailing_url}'), :id => 'newsletter-public-link') | ||
115 | + end | ||
116 | + | ||
117 | + def message_to_unsubscribe | ||
118 | + content_tag(:div, N_("This is an automatically generated email, please do not reply. If you do not wish to receive future newsletter emails, %s.") % link_to(N_("cancel your subscription here"), self.unsubscribe_url, :style => CSS['public-link']), :style => CSS['newsletter-unsubscribe'], :id => 'newsletter-unsubscribe') | ||
119 | + end | ||
120 | + | ||
121 | + def read_more(link_address) | ||
122 | + content_tag(:p, link_to(N_('Read more'), link_address, :style => CSS['read-more-link']), :style => CSS['read-more-line']) | ||
123 | + end | ||
124 | + | ||
125 | + def post_with_image(post) | ||
126 | + content_tag(:tr,content_tag(:td,tag(:img, :src => "#{self.environment.top_url}#{post.image.public_filename(:big)}", :id => post.id),:style => CSS['post-image'])+content_tag(:td,content_tag(:span, show_date(post.published_at), :style => CSS['post-date'])+content_tag(:h3, link_to(h(post.title), post.url, :style => CSS['post-title']))+content_tag(:p,sanitize(post.lead(190)),:style => CSS['post-lead'])+read_more(post.url), :style => CSS['post-info'])) | ||
127 | + end | ||
128 | + | ||
129 | + def post_without_image(post) | ||
130 | + content_tag(:tr, content_tag(:td,content_tag(:span, show_date(post.published_at),:style => CSS['post-date'], :id => post.id)+content_tag(:h3, link_to(h(post.title), post.url,:style => CSS['post-title']))+content_tag(:p,sanitize(post.lead(360)),:style => CSS['post-lead'])+read_more(post.url),:colspan => 2, :style => CSS['post-info'])) | ||
131 | + end | ||
132 | + | ||
133 | + def body(data = {}) | ||
134 | + content_tag(:div, content_tag(:div, message_to_public_link, :style => CSS['newsletter-public-link'])+content_tag(:table,(self.image.nil? ? '' : content_tag(:tr, content_tag(:th, tag(:img, :src => "#{self.environment.top_url}#{self.image.public_filename}", :style => CSS['header-image']),:colspan => 2),:style => CSS['newsletter-header']))+self.posts(data).map do |post| | ||
135 | + if post.image | ||
136 | + post_with_image(post) | ||
137 | + else | ||
138 | + post_without_image(post) | ||
139 | + end | ||
140 | + end.join()+content_tag(:tr, content_tag(:td, self.footer, :colspan => 2)),:style => CSS['breakingnews'])+content_tag(:div,message_to_unsubscribe, :style => CSS['newsletter-unsubscribe']),:style => CSS['breakingnews-wrap']) | ||
141 | + end | ||
142 | + | ||
143 | + def default_subject | ||
144 | + N_('Breaking news') | ||
145 | + end | ||
146 | + | ||
147 | + def subject | ||
148 | + self[:subject] || default_subject | ||
149 | + end | ||
150 | + | ||
151 | + def import_recipients(file, name_column = nil, email_column = nil, headers = nil) | ||
152 | + name_column ||= 1 | ||
153 | + email_column ||= 2 | ||
154 | + headers ||= false | ||
155 | + | ||
156 | + if File.extname(file.original_filename) == '.csv' | ||
157 | + parsed_recipients = [] | ||
158 | + CSV.foreach(file.path, headers: headers) do |row| | ||
159 | + parsed_recipients << {name: row[name_column.to_i - 1], email: row[email_column.to_i - 1]} | ||
160 | + end | ||
161 | + self.additional_recipients = parsed_recipients | ||
162 | + else | ||
163 | + #FIXME find a better way to deal with errors | ||
164 | + self.errors.add(:additional_recipients, _("have unknown file type: %s" % file.original_filename)) | ||
165 | + end | ||
166 | + end | ||
167 | + | ||
168 | + acts_as_having_image | ||
169 | + | ||
170 | + def last_send_at | ||
171 | + last_mailing = NewsletterPlugin::NewsletterMailing.last( | ||
172 | + :conditions => {:source_id => self.id} | ||
173 | + ) | ||
174 | + last_mailing.nil? ? nil : last_mailing.created_at | ||
175 | + end | ||
176 | + | ||
177 | + def sanitize(html) | ||
178 | + html.gsub(/<\/?p>/, '') | ||
179 | + end | ||
180 | + | ||
181 | + def has_posts_in_the_period? | ||
182 | + ! self.posts.empty? | ||
183 | + end | ||
184 | + | ||
185 | + serialize :unsubscribers, Array | ||
186 | + | ||
187 | + def unsubscribe(email) | ||
188 | + unsubscribers.push(email).uniq! | ||
189 | + end | ||
190 | + | ||
191 | +end |
plugins/newsletter/lib/newsletter_plugin/newsletter_mailing.rb
0 → 100644
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +class NewsletterPlugin::NewsletterMailing < EnvironmentMailing | ||
2 | + | ||
3 | + attr_accessible :source, :person, :locale | ||
4 | + | ||
5 | + validates_presence_of :person | ||
6 | + | ||
7 | + def url | ||
8 | + "#{self.source.top_url}/plugin/newsletter/mailing/#{self.id}" | ||
9 | + end | ||
10 | + | ||
11 | + def source | ||
12 | + NewsletterPlugin::Newsletter.find(source_id) | ||
13 | + end | ||
14 | + | ||
15 | + def deliver | ||
16 | + source.additional_recipients.each do |recipient| | ||
17 | + begin | ||
18 | + Mailing::Sender.notification(self, recipient[:email]).deliver | ||
19 | + rescue Exception => ex | ||
20 | + Rails.logger.error("#{ex.class.to_s} - #{ex.to_s} at #{__FILE__}:#{__LINE__}") | ||
21 | + end | ||
22 | + end | ||
23 | + super | ||
24 | + end | ||
25 | + | ||
26 | +end |
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +jQuery(function($) { | ||
2 | + $(".newsletter-toggle-link").live('click', function(){ | ||
3 | + element_id = this.getAttribute('element_id'); | ||
4 | + toggle_link = this; | ||
5 | + $(element_id).slideToggle(400, function() { | ||
6 | + if ($(toggle_link).find('.ui-icon').hasClass('ui-icon-triangle-1-s')) | ||
7 | + $(toggle_link).find('.ui-icon') | ||
8 | + .removeClass('ui-icon-triangle-1-s') | ||
9 | + .addClass('ui-icon-triangle-1-n'); | ||
10 | + else | ||
11 | + $(toggle_link).find('.ui-icon') | ||
12 | + .removeClass('ui-icon-triangle-1-n') | ||
13 | + .addClass('ui-icon-triangle-1-s'); | ||
14 | + }); | ||
15 | + return false; | ||
16 | + }); | ||
17 | + | ||
18 | + $('#file_recipients').change(function(){ | ||
19 | + $('#newsletter-file-options input').enable(); | ||
20 | + }); | ||
21 | +}); |
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +.newsletter-toggle-link { | ||
2 | + cursor: pointer; | ||
3 | +} | ||
4 | +#newsletter-footer-field { | ||
5 | + display: none; | ||
6 | +} | ||
7 | +#newsletter-enabled-field input#settings_enabled { | ||
8 | + margin-right: 6px; | ||
9 | +} | ||
10 | + | ||
11 | +#newsletter-moderation-preview #newsletter-public-link, | ||
12 | +#newsletter-moderation-preview #newsletter-unsubscribe { | ||
13 | + display: none; | ||
14 | +} | ||
15 | + | ||
16 | +#newsletter-moderation-preview { | ||
17 | + margin-left: 25px; | ||
18 | +} | ||
19 | + | ||
20 | +#newsletter-moderation-preview input[type=checkbox] { | ||
21 | + margin-left: -27px; | ||
22 | + margin-top: 16px; | ||
23 | + float: left; | ||
24 | +} |
plugins/newsletter/test/functional/newsletter_plugin_admin_controller_test.rb
0 → 100644
@@ -0,0 +1,176 @@ | @@ -0,0 +1,176 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
2 | + | ||
3 | +class NewsletterPluginAdminControllerTest < ActionController::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @controller = NewsletterPluginAdminController.new | ||
7 | + @request = ActionController::TestRequest.new | ||
8 | + @response = ActionController::TestResponse.new | ||
9 | + | ||
10 | + @admin = create_user('admin_newsletter').person | ||
11 | + @environment = @admin.environment | ||
12 | + @environment.add_admin(@admin) | ||
13 | + | ||
14 | + @environment.enable_plugin(NewsletterPlugin) | ||
15 | + @controller.stubs(:environment).returns(@environment) | ||
16 | + end | ||
17 | + | ||
18 | + should 'allow access to admin' do | ||
19 | + login_as @admin.identifier | ||
20 | + get :index | ||
21 | + assert_response :success | ||
22 | + end | ||
23 | + | ||
24 | + should 'save footer setting' do | ||
25 | + login_as @admin.identifier | ||
26 | + post :index, | ||
27 | + :newsletter => { :footer => 'footer of newsletter' } | ||
28 | + | ||
29 | + assert_equal 'footer of newsletter', assigns(:newsletter).footer | ||
30 | + end | ||
31 | + | ||
32 | + | ||
33 | + should 'save header image' do | ||
34 | + login_as @admin.identifier | ||
35 | + post :index, | ||
36 | + :newsletter => { | ||
37 | + :image_builder => { | ||
38 | + :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png') | ||
39 | + } | ||
40 | + } | ||
41 | + assert_equal 'rails.png', assigns(:newsletter).image.filename | ||
42 | + end | ||
43 | + | ||
44 | + should 'save enabled newsletter information' do | ||
45 | + login_as @admin.identifier | ||
46 | + post :index, | ||
47 | + :newsletter => { :enabled => 'true' } | ||
48 | + | ||
49 | + newsletter = NewsletterPlugin::Newsletter.find_by_environment_id(@environment.id) | ||
50 | + | ||
51 | + assert newsletter.enabled | ||
52 | + end | ||
53 | + | ||
54 | + should 'save periodicity newsletter information' do | ||
55 | + login_as @admin.identifier | ||
56 | + post :index, | ||
57 | + :newsletter => { :periodicity => '10' } | ||
58 | + | ||
59 | + newsletter = NewsletterPlugin::Newsletter.find_by_environment_id(@environment.id) | ||
60 | + | ||
61 | + assert_equal 10, newsletter.periodicity | ||
62 | + end | ||
63 | + | ||
64 | + should 'save number of posts per blog setting' do | ||
65 | + login_as @admin.identifier | ||
66 | + post :index, | ||
67 | + :newsletter => { :posts_per_blog => '6' } | ||
68 | + | ||
69 | + assert_equal 6, assigns(:newsletter).posts_per_blog | ||
70 | + end | ||
71 | + | ||
72 | + should 'show error if number of posts per blog is not a positive number' do | ||
73 | + login_as @admin.identifier | ||
74 | + post :index, | ||
75 | + :newsletter => { :posts_per_blog => '-4' } | ||
76 | + | ||
77 | + assert_select 'li', 'Posts per blog must be a positive number' | ||
78 | + end | ||
79 | + | ||
80 | + should 'save blogs for compiling newsletter setting' do | ||
81 | + login_as @admin.identifier | ||
82 | + | ||
83 | + blog1 = fast_create(Blog) | ||
84 | + blog1.profile = fast_create(Profile, environment_id: @environment.id) | ||
85 | + blog1.save | ||
86 | + | ||
87 | + blog2 = fast_create(Blog) | ||
88 | + blog2.profile = fast_create(Profile, environment_id: @environment.id) | ||
89 | + blog2.save | ||
90 | + | ||
91 | + post :index, | ||
92 | + :newsletter => { :blog_ids => "#{blog1.id},#{blog2.id}" } | ||
93 | + | ||
94 | + assert_equivalent [blog1.id,blog2.id], assigns(:newsletter).blog_ids | ||
95 | + end | ||
96 | + | ||
97 | + should 'show error if blog is not in environment' do | ||
98 | + login_as @admin.identifier | ||
99 | + | ||
100 | + blog = fast_create(Blog) | ||
101 | + blog.profile = fast_create(Profile, environment_id: fast_create(Environment).id) | ||
102 | + blog.save | ||
103 | + | ||
104 | + post :index, | ||
105 | + :newsletter => { :blog_ids => "#{blog.id}" } | ||
106 | + | ||
107 | + assert_select 'li', 'Blog ids must be valid' | ||
108 | + end | ||
109 | + | ||
110 | + should 'save logged in admin as person' do | ||
111 | + login_as @admin.identifier | ||
112 | + post :index, :newsletter => { } | ||
113 | + | ||
114 | + assert_equal @admin, assigns(:newsletter).person | ||
115 | + end | ||
116 | + | ||
117 | + should 'receive csv file from user' do | ||
118 | + content = <<-EOS | ||
119 | +Coop1,name1@example.com | ||
120 | +Coop2,name2@example.com | ||
121 | +Coop3,name3@example.com | ||
122 | +EOS | ||
123 | + | ||
124 | + file = Tempfile.new(['recipients', '.csv']) | ||
125 | + file.write(content) | ||
126 | + file.rewind | ||
127 | + | ||
128 | + login_as @admin.identifier | ||
129 | + post :index, newsletter: {}, :file => { recipients: Rack::Test::UploadedFile.new(file, 'text/csv') } | ||
130 | + | ||
131 | + file.close | ||
132 | + file.unlink | ||
133 | + | ||
134 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:email] } | ||
135 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:name] } | ||
136 | + end | ||
137 | + | ||
138 | + should 'parse csv file with configuration set by user' do | ||
139 | + content = <<-EOS | ||
140 | +Id,Name,City,Email | ||
141 | +1,Coop1,Moscow,name1@example.com | ||
142 | +2,Coop2,Beijing,name2@example.com | ||
143 | +3,Coop3,Paris,name3@example.com | ||
144 | +EOS | ||
145 | + | ||
146 | + file = Tempfile.new(['recipients', '.csv']) | ||
147 | + file.write(content) | ||
148 | + file.rewind | ||
149 | + | ||
150 | + login_as @admin.identifier | ||
151 | + post :index, newsletter: {}, :file => { recipients: Rack::Test::UploadedFile.new(file, 'text/csv'), headers: 1, name: 2, email: 4 } | ||
152 | + | ||
153 | + file.close | ||
154 | + file.unlink | ||
155 | + | ||
156 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:email] } | ||
157 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], assigns(:newsletter).additional_recipients.map { |recipient| recipient[:name] } | ||
158 | + end | ||
159 | + | ||
160 | + should 'list additional recipients' do | ||
161 | + login_as @admin.identifier | ||
162 | + get :recipients | ||
163 | + assert_select 'p', 'There are no additional recipients.' | ||
164 | + | ||
165 | + newsletter = NewsletterPlugin::Newsletter.create!(environment: @environment, person: fast_create(Person)) | ||
166 | + newsletter.additional_recipients = [ {name: 'Coop1', email: 'name1@example.com'} ] | ||
167 | + newsletter.save! | ||
168 | + | ||
169 | + get :recipients | ||
170 | + assert_select 'tr' do | ||
171 | + assert_select 'td', 'Coop1' | ||
172 | + assert_select 'td', 'name1@example.com' | ||
173 | + end | ||
174 | + end | ||
175 | + | ||
176 | +end |
plugins/newsletter/test/functional/newsletter_plugin_controller_test.rb
0 → 100644
@@ -0,0 +1,37 @@ | @@ -0,0 +1,37 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
2 | + | ||
3 | +class NewsletterPluginControllerTest < ActionController::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @controller = NewsletterPluginController.new | ||
7 | + @request = ActionController::TestRequest.new | ||
8 | + @response = ActionController::TestResponse.new | ||
9 | + environment = fast_create(Environment) | ||
10 | + environment.enable_plugin(NewsletterPlugin) | ||
11 | + @controller.stubs(:environment).returns(environment) | ||
12 | + end | ||
13 | + | ||
14 | + should 'require login to confirm unsubscription' do | ||
15 | + post :confirm_unsubscription | ||
16 | + assert_response 302 | ||
17 | + end | ||
18 | + | ||
19 | + should 'open unsubscription page for anonymous' do | ||
20 | + get :unsubscribe | ||
21 | + assert_response :success | ||
22 | + end | ||
23 | + | ||
24 | + should 'add user email from unsubscribers list' do | ||
25 | + NewsletterPlugin::Newsletter.create!( | ||
26 | + :environment => @controller.environment, | ||
27 | + :person => fast_create(Person) | ||
28 | + ) | ||
29 | + maria = create_user("maria").person | ||
30 | + login_as("maria") | ||
31 | + post :confirm_unsubscription | ||
32 | + assert_response :redirect | ||
33 | + assert_redirected_to :controller => 'home' | ||
34 | + assert_includes assigns(:newsletter).unsubscribers, maria.email | ||
35 | + end | ||
36 | + | ||
37 | +end |
plugins/newsletter/test/unit/newsletter_plugin_moderate_newsletter_test.rb
0 → 100644
@@ -0,0 +1,50 @@ | @@ -0,0 +1,50 @@ | ||
1 | +require 'test_helper' | ||
2 | + | ||
3 | +class NewsletterPluginModerateNewsletterTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + should 'validates presence of newsletter_id' do | ||
6 | + task = NewsletterPlugin::ModerateNewsletter.new | ||
7 | + task.valid? | ||
8 | + assert task.errors.include?(:newsletter_id) | ||
9 | + | ||
10 | + task.newsletter_id = 1 | ||
11 | + task.valid? | ||
12 | + refute task.errors.include?(:newsletter_id) | ||
13 | + end | ||
14 | + | ||
15 | + should 'create mailing on perform' do | ||
16 | + person = create_user('john').person | ||
17 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => fast_create(Environment), :person => person, :enabled => true) | ||
18 | + task = NewsletterPlugin::ModerateNewsletter.create!( | ||
19 | + :newsletter_id => newsletter.id, | ||
20 | + :target => newsletter.environment | ||
21 | + ) | ||
22 | + | ||
23 | + assert_difference 'NewsletterPlugin::NewsletterMailing.count', 1 do | ||
24 | + task.finish | ||
25 | + end | ||
26 | + end | ||
27 | + | ||
28 | + should 'set posts for mailing body on perform' do | ||
29 | + person = create_user('john').person | ||
30 | + blog = fast_create(Blog, profile_id: person.id) | ||
31 | + post_1 = fast_create(TextileArticle, :name => 'First post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
32 | + post_2 = fast_create(TextileArticle, :name => 'Second post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
33 | + post_3 = fast_create(TextileArticle, :name => 'Third post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
34 | + | ||
35 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => person.environment, :person => person, :enabled => true) | ||
36 | + newsletter.blog_ids = [blog.id] | ||
37 | + newsletter.save! | ||
38 | + | ||
39 | + task = NewsletterPlugin::ModerateNewsletter.create!( | ||
40 | + :newsletter_id => newsletter.id, | ||
41 | + :target => newsletter.environment, | ||
42 | + :post_ids => [post_1.id.to_s,post_2.id.to_s] | ||
43 | + ) | ||
44 | + | ||
45 | + task.finish | ||
46 | + assert_match /First post/, NewsletterPlugin::NewsletterMailing.last.body | ||
47 | + assert_match /Second post/, NewsletterPlugin::NewsletterMailing.last.body | ||
48 | + assert_not_match /Third post/, NewsletterPlugin::NewsletterMailing.last.body | ||
49 | + end | ||
50 | +end |
plugins/newsletter/test/unit/newsletter_plugin_newsletter_mailing_test.rb
0 → 100644
@@ -0,0 +1,72 @@ | @@ -0,0 +1,72 @@ | ||
1 | +require 'test_helper' | ||
2 | + | ||
3 | +class NewsletterPluginNewsletterMailingTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + ActionMailer::Base.delivery_method = :test | ||
7 | + ActionMailer::Base.perform_deliveries = true | ||
8 | + ActionMailer::Base.deliveries = [] | ||
9 | + end | ||
10 | + | ||
11 | + should 'require source id' do | ||
12 | + mailing = NewsletterPlugin::NewsletterMailing.new | ||
13 | + mailing.valid? | ||
14 | + assert mailing.errors[:source_id].any? | ||
15 | + | ||
16 | + mailing.source_id = NewsletterPlugin::Newsletter.create!(:environment => fast_create(Environment), :person => fast_create(Person)).id | ||
17 | + mailing.valid? | ||
18 | + refute mailing.errors[:source_id].any? | ||
19 | + end | ||
20 | + | ||
21 | + should 'deliver mail from noreply environment email address' do | ||
22 | + environment = fast_create(Environment, :noreply_email => 'noreply@localhost') | ||
23 | + person = fast_create Person | ||
24 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => person, :enabled => true) | ||
25 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | ||
26 | + :source => newsletter, | ||
27 | + :subject => newsletter.subject, | ||
28 | + :body => newsletter.body, | ||
29 | + :person => newsletter.person, | ||
30 | + :locale => environment.default_locale, | ||
31 | + ) | ||
32 | + response = NewsletterPlugin::NewsletterMailing::Sender.notification(mailing, 'recipient@example.com').deliver | ||
33 | + assert_equal 'noreply@localhost', response.from.join | ||
34 | + end | ||
35 | + | ||
36 | + should 'also send to additional recipients' do | ||
37 | + environment = fast_create(Environment, :name => 'Network') | ||
38 | + person = create_user('betty', :environment_id => environment.id).person | ||
39 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => person) | ||
40 | + | ||
41 | + newsletter.additional_recipients = [{name: 'example', email: 'exemple@mail.co'}, {name: 'jon', email: 'jonsnow@mail.co'}] | ||
42 | + newsletter.save! | ||
43 | + | ||
44 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | ||
45 | + :source => newsletter, | ||
46 | + :subject => newsletter.subject, | ||
47 | + :body => newsletter.body, | ||
48 | + :person => newsletter.person, | ||
49 | + :locale => newsletter.environment.default_locale, | ||
50 | + ) | ||
51 | + | ||
52 | + process_delayed_job_queue | ||
53 | + assert_equal 3, ActionMailer::Base.deliveries.count | ||
54 | + end | ||
55 | + | ||
56 | + should 'generate url to view mailing' do | ||
57 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
58 | + :environment => fast_create(Environment), | ||
59 | + :person => fast_create(Person), | ||
60 | + :enabled => true | ||
61 | + ) | ||
62 | + mailing = NewsletterPlugin::NewsletterMailing.create!( | ||
63 | + :source => newsletter, | ||
64 | + :subject => newsletter.subject, | ||
65 | + :body => newsletter.body, | ||
66 | + :person => newsletter.person, | ||
67 | + :locale => newsletter.environment.default_locale, | ||
68 | + ) | ||
69 | + assert_equal "http://localhost/plugin/newsletter/mailing/#{mailing.id}", mailing.url | ||
70 | + end | ||
71 | + | ||
72 | +end |
plugins/newsletter/test/unit/newsletter_plugin_newsletter_test.rb
0 → 100644
@@ -0,0 +1,414 @@ | @@ -0,0 +1,414 @@ | ||
1 | +require 'test_helper' | ||
2 | + | ||
3 | +class NewsletterPluginNewsletterTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + should 'throws exception when try to create newsletters without reference do environment' do | ||
6 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
7 | + NewsletterPlugin::Newsletter.create! | ||
8 | + assert_match /Profile can't be blank/, e.to_s | ||
9 | + end | ||
10 | + end | ||
11 | + | ||
12 | + should 'allow save only one newsletter by environment' do | ||
13 | + environment = fast_create Environment | ||
14 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | ||
15 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
16 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | ||
17 | + assert_match /Profile has already been taken/, e.to_s | ||
18 | + end | ||
19 | + end | ||
20 | + | ||
21 | + should 'collect enabled newsletters' do | ||
22 | + enabled_newsletters = [] | ||
23 | + 5.times do | ||
24 | + environment = fast_create(Environment) | ||
25 | + enabled = environment.id % 2 == 0 | ||
26 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
27 | + :environment => environment, | ||
28 | + :enabled => enabled, | ||
29 | + :person => fast_create(Person)) | ||
30 | + enabled_newsletters << newsletter.id if enabled | ||
31 | + end | ||
32 | + assert_equal enabled_newsletters, NewsletterPlugin::Newsletter.enabled.map(&:id) | ||
33 | + end | ||
34 | + | ||
35 | + should 'people of newsletters are the same environment members' do | ||
36 | + 3.times do | ||
37 | + environment = fast_create(Environment) | ||
38 | + 3.times do | ||
39 | + fast_create(Person, environment_id: environment) | ||
40 | + end | ||
41 | + NewsletterPlugin::Newsletter.create!( | ||
42 | + :environment => environment, | ||
43 | + :enabled => true, | ||
44 | + :person => fast_create(Person)) | ||
45 | + end | ||
46 | + NewsletterPlugin::Newsletter.enabled.each do |newsletter| | ||
47 | + assert_not_equal [], newsletter.people | ||
48 | + assert_equal newsletter.environment.people, newsletter.people | ||
49 | + end | ||
50 | + end | ||
51 | + | ||
52 | + should 'save period for newsletter' do | ||
53 | + environment = fast_create Environment | ||
54 | + NewsletterPlugin::Newsletter.create!( | ||
55 | + :environment => environment, | ||
56 | + :periodicity => '3', | ||
57 | + :person => fast_create(Person)) | ||
58 | + | ||
59 | + assert_equal 3, NewsletterPlugin::Newsletter.find_by_environment_id(environment.id).periodicity | ||
60 | + end | ||
61 | + | ||
62 | + should 'save period as number only' do | ||
63 | + environment = fast_create Environment | ||
64 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
65 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :periodicity => 'one week' ) | ||
66 | + assert_match /Periodicity must be a positive number/, e.to_s | ||
67 | + end | ||
68 | + end | ||
69 | + | ||
70 | + should 'save period as a positive number only' do | ||
71 | + environment = fast_create Environment | ||
72 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
73 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :periodicity => -1 ) | ||
74 | + assert_match /Periodicity must be a positive number/, e.to_s | ||
75 | + end | ||
76 | + end | ||
77 | + | ||
78 | + should 'save reference to environment blog' do | ||
79 | + environment = fast_create Environment | ||
80 | + blog = fast_create(Blog) | ||
81 | + blog.profile = fast_create(Profile, environment_id: environment.id) | ||
82 | + blog.save | ||
83 | + assert_nothing_raised ActiveRecord::RecordInvalid do | ||
84 | + NewsletterPlugin::Newsletter.create!( | ||
85 | + :environment => environment, | ||
86 | + :blog_ids => [blog.id], | ||
87 | + :person => fast_create(Person)) | ||
88 | + end | ||
89 | + end | ||
90 | + | ||
91 | + should 'not save reference to unknown blog' do | ||
92 | + environment = fast_create Environment | ||
93 | + blog = fast_create(Blog) | ||
94 | + blog.profile = fast_create(Profile, environment_id: fast_create(Environment).id) | ||
95 | + blog.save | ||
96 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
97 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :blog_ids => [blog.id]) | ||
98 | + assert_match /Blog ids must be valid/, e.to_s | ||
99 | + end | ||
100 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
101 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :blog_ids => [blog.id*2]) | ||
102 | + assert_match /Blog ids must be valid/, e.to_s | ||
103 | + end | ||
104 | + end | ||
105 | + | ||
106 | + should 'not save duplicates for blog ids' do | ||
107 | + environment = fast_create Environment | ||
108 | + blog = fast_create(Blog) | ||
109 | + blog.profile = fast_create(Profile, environment_id: environment.id) | ||
110 | + blog.save | ||
111 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
112 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :blog_ids => [blog.id, blog.id]) | ||
113 | + assert_match /Blog ids must not have duplicates/, e.to_s | ||
114 | + end | ||
115 | + end | ||
116 | + | ||
117 | + should "not send newsletters if periodicity isn't expired" do | ||
118 | + newsletter = NewsletterPlugin::Newsletter.new | ||
119 | + newsletter.periodicity = 10 | ||
120 | + newsletter.stubs(:last_send_at).returns(DateTime.parse("2015-01-01")) | ||
121 | + Date.stubs(:today).returns(Date.parse("2015-01-07")) | ||
122 | + assert_equal false, newsletter.must_be_sent_today? | ||
123 | + end | ||
124 | + | ||
125 | + should 'send newsletters when periodicity expires' do | ||
126 | + newsletter = NewsletterPlugin::Newsletter.new | ||
127 | + newsletter.periodicity = 10 | ||
128 | + newsletter.stubs(:last_send_at).returns(DateTime.parse("2015-01-01")) | ||
129 | + Date.stubs(:today).returns(Date.parse("2015-01-15")) | ||
130 | + assert_equal true, newsletter.must_be_sent_today? | ||
131 | + end | ||
132 | + | ||
133 | + should 'send now if never send before' do | ||
134 | + newsletter = NewsletterPlugin::Newsletter.new(:environment => fast_create(Environment)) | ||
135 | + newsletter.periodicity = 10 | ||
136 | + assert newsletter.must_be_sent_today? | ||
137 | + end | ||
138 | + | ||
139 | + should 'validate email format for additional recipients' do | ||
140 | + environment = fast_create Environment | ||
141 | + assert_raises ActiveRecord::RecordInvalid do |e| | ||
142 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person), additional_recipients: [{name: 'Cooperative', email: 'cooperative@example'}]) | ||
143 | + assert_match /Additional recipients must have only valid emails/, e.to_s | ||
144 | + end | ||
145 | + assert_nothing_raised ActiveRecord::RecordInvalid do |e| | ||
146 | + NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person), additional_recipients: [{name: 'Cooperative', email: 'cooperative@example.com'}]) | ||
147 | + end | ||
148 | + end | ||
149 | + | ||
150 | + should 'parse additional recipients' do | ||
151 | + content = <<-EOS | ||
152 | +Coop1,name1@example.com | ||
153 | +Coop2,name2@example.com | ||
154 | +Coop3,name3@example.com | ||
155 | +EOS | ||
156 | + | ||
157 | + file = Tempfile.new(['recipients', '.csv']) | ||
158 | + file.write(content) | ||
159 | + file.rewind | ||
160 | + | ||
161 | + environment = fast_create Environment | ||
162 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | ||
163 | + newsletter.import_recipients(Rack::Test::UploadedFile.new(file, 'text/csv')) | ||
164 | + | ||
165 | + file.close | ||
166 | + file.unlink | ||
167 | + | ||
168 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], newsletter.additional_recipients.map { |recipient| recipient[:email] } | ||
169 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], newsletter.additional_recipients.map { |recipient| recipient[:name] } | ||
170 | + end | ||
171 | + | ||
172 | + should 'only parse csv files' do | ||
173 | + content = <<-EOS | ||
174 | +Coop1,name1@example.com | ||
175 | +Coop2,name2@example.com | ||
176 | +Coop3,name3@example.com | ||
177 | +EOS | ||
178 | + | ||
179 | + file = Tempfile.new(['recipients', '.txt']) | ||
180 | + file.write(content) | ||
181 | + file.rewind | ||
182 | + | ||
183 | + environment = fast_create Environment | ||
184 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | ||
185 | + newsletter.import_recipients(Rack::Test::UploadedFile.new(file)) | ||
186 | + | ||
187 | + file.close | ||
188 | + file.unlink | ||
189 | + | ||
190 | + assert_equal [], newsletter.additional_recipients | ||
191 | + assert_match /Additional recipients have unknown file type.*/, newsletter.errors.full_messages[0] | ||
192 | + end | ||
193 | + | ||
194 | + should 'parse additional recipients with given column number and header' do | ||
195 | + content = <<-EOS | ||
196 | +Id,Name,City,Email | ||
197 | +1,Coop1,Moscow,name1@example.com | ||
198 | +2,Coop2,Beijing,name2@example.com | ||
199 | +3,Coop3,Paris,name3@example.com | ||
200 | +EOS | ||
201 | + | ||
202 | + file = Tempfile.new(['recipients', '.csv']) | ||
203 | + file.write(content) | ||
204 | + file.rewind | ||
205 | + | ||
206 | + environment = fast_create Environment | ||
207 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | ||
208 | + newsletter.import_recipients(Rack::Test::UploadedFile.new(file, 'text/csv'), 2, 4, true) | ||
209 | + | ||
210 | + file.close | ||
211 | + file.unlink | ||
212 | + | ||
213 | + assert_equivalent ["name1@example.com", "name2@example.com", "name3@example.com"], newsletter.additional_recipients.map { |recipient| recipient[:email] } | ||
214 | + assert_equivalent ["Coop1", "Coop2", "Coop3"], newsletter.additional_recipients.map { |recipient| recipient[:name] } | ||
215 | + end | ||
216 | + | ||
217 | + should 'retrieve blogs related to newsletter' do | ||
218 | + environment = fast_create Environment | ||
219 | + community = fast_create(Community, :environment_id => environment.id) | ||
220 | + blog1 = fast_create(Blog, :profile_id => community.id) | ||
221 | + blog2 = fast_create(Blog, :profile_id => community.id) | ||
222 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
223 | + :environment => environment, :blog_ids => [blog1.id, blog2.id], :person => fast_create(Person) | ||
224 | + ) | ||
225 | + assert_equivalent [blog1, blog2], newsletter.blogs | ||
226 | + end | ||
227 | + | ||
228 | + should 'return empty if has no related blogs' do | ||
229 | + environment = fast_create Environment | ||
230 | + newsletter = NewsletterPlugin::Newsletter.create!(:environment => environment, :person => fast_create(Person)) | ||
231 | + assert_empty newsletter.blogs | ||
232 | + end | ||
233 | + | ||
234 | + should 'list posts for all selected blogs' do | ||
235 | + environment = fast_create Environment | ||
236 | + community = fast_create(Community, :environment_id => environment.id) | ||
237 | + blog = fast_create(Blog, :profile_id => community.id) | ||
238 | + post = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news') | ||
239 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
240 | + :environment => environment, | ||
241 | + :blog_ids => [blog.id], | ||
242 | + :person => fast_create(Person)) | ||
243 | + assert_includes newsletter.posts, post | ||
244 | + end | ||
245 | + | ||
246 | + should 'generate HTML content using posts of selected blogs' do | ||
247 | + environment = fast_create Environment | ||
248 | + community = fast_create(Community, :environment_id => environment.id) | ||
249 | + blog = fast_create(Blog, :profile_id => community.id) | ||
250 | + fast_create(TextArticle, :profile_id => community.id, :parent_id => blog.id, :name => 'the last news') | ||
251 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
252 | + :environment => environment, | ||
253 | + :blog_ids => [blog.id], | ||
254 | + :person => fast_create(Person)) | ||
255 | + assert_tag_in_string newsletter.body, :tag => 'a', :content => 'the last news' | ||
256 | + end | ||
257 | + | ||
258 | + should 'limit the number of posts per blog' do | ||
259 | + environment = fast_create Environment | ||
260 | + community = fast_create(Community, :environment_id => environment.id) | ||
261 | + blog = fast_create(Blog, :profile_id => community.id) | ||
262 | + fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 1') | ||
263 | + fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 2') | ||
264 | + fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 3') | ||
265 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
266 | + :environment => environment, | ||
267 | + :blog_ids => [blog.id], | ||
268 | + :person => fast_create(Person), | ||
269 | + :posts_per_blog => 2) | ||
270 | + assert_equal 2, newsletter.posts.count | ||
271 | + end | ||
272 | + | ||
273 | + should 'include all posts before today' do | ||
274 | + environment = fast_create Environment | ||
275 | + community = fast_create(Community, :environment_id => environment.id) | ||
276 | + blog = fast_create(Blog, :profile_id => community.id) | ||
277 | + | ||
278 | + post1 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 1', | ||
279 | + :published_at => DateTime.parse("2015-01-01")) | ||
280 | + post2 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 2', | ||
281 | + :published_at => DateTime.parse("2015-01-09")) | ||
282 | + | ||
283 | + Date.stubs(:today).returns(DateTime.parse("2015-01-10").to_date) | ||
284 | + | ||
285 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
286 | + :environment => environment, | ||
287 | + :blog_ids => [blog.id], | ||
288 | + :person => fast_create(Person)) | ||
289 | + | ||
290 | + newsletter_posts = newsletter.posts | ||
291 | + assert_includes newsletter_posts, post1 | ||
292 | + assert_includes newsletter_posts, post2 | ||
293 | + end | ||
294 | + | ||
295 | + should 'not include posts already sent' do | ||
296 | + environment = fast_create Environment | ||
297 | + community = fast_create(Community, :environment_id => environment.id) | ||
298 | + blog = fast_create(Blog, :profile_id => community.id) | ||
299 | + | ||
300 | + post1 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 1', | ||
301 | + :published_at => DateTime.parse("2015-01-01")) | ||
302 | + post2 = fast_create(TextArticle, :parent_id => blog.id, :name => 'the last news 2', | ||
303 | + :published_at => DateTime.parse("2015-01-09")) | ||
304 | + | ||
305 | + Date.stubs(:today).returns(DateTime.parse("2015-01-10").to_date) | ||
306 | + | ||
307 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
308 | + :environment => environment, | ||
309 | + :blog_ids => [blog.id], | ||
310 | + :person => fast_create(Person)) | ||
311 | + newsletter.stubs(:last_send_at).returns(DateTime.parse("2015-01-05")) | ||
312 | + | ||
313 | + newsletter_posts = newsletter.posts | ||
314 | + assert_not_includes newsletter_posts, post1 | ||
315 | + assert_includes newsletter_posts, post2 | ||
316 | + end | ||
317 | + | ||
318 | + should 'sanitize tags <p> from news lead' do | ||
319 | + environment = fast_create Environment | ||
320 | + community = fast_create(Community, :environment_id => environment.id) | ||
321 | + blog = fast_create(Blog, :profile_id => community.id) | ||
322 | + post = fast_create(TextArticle, :parent_id => blog.id, | ||
323 | + :name => 'the last news 1', | ||
324 | + :profile_id => community.id, | ||
325 | + :body => "<p>paragraph of news</p>") | ||
326 | + | ||
327 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
328 | + :environment => environment, | ||
329 | + :blog_ids => [blog.id], | ||
330 | + :person => fast_create(Person)) | ||
331 | + | ||
332 | + assert_match /<p>paragraph of news<\/p>/, post.body | ||
333 | + assert_not_match /<p>paragraph of news<\/p>/, newsletter.body | ||
334 | + end | ||
335 | + | ||
336 | + should 'filter posts when listing posts for newsletter' do | ||
337 | + person = fast_create(Person) | ||
338 | + blog = fast_create(Blog, profile_id: person.id) | ||
339 | + | ||
340 | + post_1 = fast_create(TextileArticle, :name => 'First post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
341 | + post_2 = fast_create(TextileArticle, :name => 'Second post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
342 | + post_3 = fast_create(TextileArticle, :name => 'Third post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
343 | + | ||
344 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
345 | + :environment => person.environment, | ||
346 | + :blog_ids => [blog.id], | ||
347 | + :person => person) | ||
348 | + | ||
349 | + assert_equivalent [post_2.id, post_3.id], newsletter.posts({post_ids: [post_2.id.to_s, post_3.id.to_s]}).map(&:id) | ||
350 | + end | ||
351 | + | ||
352 | + should 'filter posts in body for newsletter' do | ||
353 | + person = fast_create(Person) | ||
354 | + blog = fast_create(Blog, profile_id: person.id) | ||
355 | + | ||
356 | + post_1 = fast_create(TextileArticle, :name => 'First post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
357 | + post_2 = fast_create(TextileArticle, :name => 'Second post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
358 | + post_3 = fast_create(TextileArticle, :name => 'Third post', :profile_id => person.id, :parent_id => blog.id, :body => 'Test') | ||
359 | + | ||
360 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
361 | + :environment => person.environment, | ||
362 | + :blog_ids => [blog.id], | ||
363 | + :person => person) | ||
364 | + | ||
365 | + assert_match /First post/, NewsletterPlugin::Newsletter.last.body({post_ids: [post_1.id.to_s, post_3.id.to_s]}) | ||
366 | + assert_not_match /Second post/, NewsletterPlugin::Newsletter.last.body({post_ids: [post_1.id.to_s, post_3.id.to_s]}) | ||
367 | + assert_match /Third post/, NewsletterPlugin::Newsletter.last.body({post_ids: [post_1.id.to_s, post_3.id.to_s]}) | ||
368 | + end | ||
369 | + | ||
370 | + should 'add email to unsubscribers list' do | ||
371 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
372 | + :environment => fast_create(Environment), | ||
373 | + :person => fast_create(Person) | ||
374 | + ) | ||
375 | + newsletter.unsubscribe("ze@localhost.localdomain") | ||
376 | + assert_includes newsletter.unsubscribers, "ze@localhost.localdomain" | ||
377 | + end | ||
378 | + | ||
379 | + should 'not add same email twice to unsubscribers list' do | ||
380 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
381 | + :environment => fast_create(Environment), | ||
382 | + :person => fast_create(Person) | ||
383 | + ) | ||
384 | + newsletter.unsubscribe("ze@localhost.localdomain") | ||
385 | + newsletter.unsubscribe("ze@localhost.localdomain") | ||
386 | + assert_equal ["ze@localhost.localdomain"], newsletter.unsubscribers | ||
387 | + end | ||
388 | + | ||
389 | + should "filter newsletter's recipients using unsubscribers list" do | ||
390 | + environment = fast_create Environment | ||
391 | + p1 = create_user("person1", :environment_id => environment.id).person | ||
392 | + p2 = create_user("person2", :environment_id => environment.id).person | ||
393 | + p3 = create_user("person3", :environment_id => environment.id).person | ||
394 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
395 | + :environment => environment, | ||
396 | + :person => fast_create(Person) | ||
397 | + ) | ||
398 | + newsletter.unsubscribe(p2.email) | ||
399 | + assert_equivalent [p1, p3], newsletter.people | ||
400 | + end | ||
401 | + | ||
402 | + should "no filter newsletter's recipients if unsubscribers list empty" do | ||
403 | + environment = fast_create Environment | ||
404 | + p1 = create_user("person1", :environment_id => environment.id).person | ||
405 | + p2 = create_user("person2", :environment_id => environment.id).person | ||
406 | + p3 = create_user("person3", :environment_id => environment.id).person | ||
407 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
408 | + :environment => environment, | ||
409 | + :person => fast_create(Person) | ||
410 | + ) | ||
411 | + assert_equivalent [p1, p2, p3], newsletter.people | ||
412 | + end | ||
413 | + | ||
414 | +end |
@@ -0,0 +1,113 @@ | @@ -0,0 +1,113 @@ | ||
1 | +require 'test_helper' | ||
2 | + | ||
3 | +class NewsletterPluginTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + NewsletterPlugin::Newsletter.any_instance.stubs(:must_be_sent_today?).returns(true) | ||
7 | + NewsletterPlugin::Newsletter.any_instance.stubs(:has_posts_in_the_period?).returns(true) | ||
8 | + end | ||
9 | + | ||
10 | + should 'update newsletter send date only for enabled newsletters' do | ||
11 | + newsletter_enabled = NewsletterPlugin::Newsletter.create!( | ||
12 | + :environment => fast_create(Environment), | ||
13 | + :enabled => true, | ||
14 | + :subject => 'newsletter test', | ||
15 | + :person => fast_create(Person)) | ||
16 | + | ||
17 | + newsletter_disabled = NewsletterPlugin::Newsletter.create!( | ||
18 | + :environment => fast_create(Environment), | ||
19 | + :enabled => false, | ||
20 | + :subject => 'newsletter test', | ||
21 | + :person => fast_create(Person)) | ||
22 | + | ||
23 | + NewsletterPlugin.compile_and_send_newsletters | ||
24 | + | ||
25 | + newsletter_enabled.reload | ||
26 | + newsletter_disabled.reload | ||
27 | + | ||
28 | + assert_not_nil newsletter_enabled.last_send_at | ||
29 | + assert_nil newsletter_disabled.last_send_at | ||
30 | + end | ||
31 | + | ||
32 | + should 'create and schedule newsletter mailing if not moderated' do | ||
33 | + NewsletterPlugin::Newsletter.create!( | ||
34 | + :environment => fast_create(Environment), | ||
35 | + :enabled => true, | ||
36 | + :moderated => false, | ||
37 | + :subject => 'newsletter test', | ||
38 | + :person => fast_create(Person)) | ||
39 | + | ||
40 | + assert_difference 'NewsletterPlugin::NewsletterMailing.count', 1 do | ||
41 | + NewsletterPlugin.compile_and_send_newsletters | ||
42 | + end | ||
43 | + | ||
44 | + assert_equal 0, NewsletterPlugin::ModerateNewsletter.count | ||
45 | + end | ||
46 | + | ||
47 | + should 'use same environment locale on mailing' do | ||
48 | + NewsletterPlugin::Newsletter.create!( | ||
49 | + :environment => fast_create(Environment, :default_language => 'pt_BR'), | ||
50 | + :enabled => true, | ||
51 | + :subject => 'newsletter test', | ||
52 | + :person => fast_create(Person)) | ||
53 | + | ||
54 | + NewsletterPlugin.compile_and_send_newsletters | ||
55 | + assert_equal 'pt_BR', NewsletterPlugin::NewsletterMailing.last.locale | ||
56 | + end | ||
57 | + | ||
58 | + should 'create newsletter moderation task if newsletter is moderated' do | ||
59 | + adminuser = create_user.person | ||
60 | + Environment.any_instance.stubs(:admins).returns([adminuser]) | ||
61 | + | ||
62 | + NewsletterPlugin::Newsletter.create!( | ||
63 | + :environment => fast_create(Environment), | ||
64 | + :enabled => true, | ||
65 | + :moderated => true, | ||
66 | + :subject => 'newsletter test', | ||
67 | + :person => fast_create(Person)) | ||
68 | + | ||
69 | + assert_difference 'NewsletterPlugin::ModerateNewsletter.count', 1 do | ||
70 | + NewsletterPlugin.compile_and_send_newsletters | ||
71 | + end | ||
72 | + | ||
73 | + assert_equal 0, NewsletterPlugin::NewsletterMailing.count | ||
74 | + end | ||
75 | + | ||
76 | + should 'not create mailing if has no posts in the period' do | ||
77 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
78 | + :environment => fast_create(Environment), | ||
79 | + :person => fast_create(Person), | ||
80 | + :enabled => true | ||
81 | + ) | ||
82 | + NewsletterPlugin::Newsletter.any_instance.stubs(:must_be_sent_today?).returns(true) | ||
83 | + NewsletterPlugin::Newsletter.any_instance.stubs(:has_posts_in_the_period?).returns(false) | ||
84 | + assert_no_difference 'NewsletterPlugin::NewsletterMailing.count' do | ||
85 | + NewsletterPlugin.compile_and_send_newsletters | ||
86 | + end | ||
87 | + end | ||
88 | + | ||
89 | + should 'not create mailing if doesnt must be sent today' do | ||
90 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
91 | + :environment => fast_create(Environment), | ||
92 | + :person => fast_create(Person), | ||
93 | + :enabled => true | ||
94 | + ) | ||
95 | + NewsletterPlugin::Newsletter.any_instance.stubs(:must_be_sent_today?).returns(false) | ||
96 | + NewsletterPlugin::Newsletter.any_instance.stubs(:has_posts_in_the_period?).returns(true) | ||
97 | + assert_no_difference 'NewsletterPlugin::NewsletterMailing.count' do | ||
98 | + NewsletterPlugin.compile_and_send_newsletters | ||
99 | + end | ||
100 | + end | ||
101 | + | ||
102 | + should 'create mailing' do | ||
103 | + newsletter = NewsletterPlugin::Newsletter.create!( | ||
104 | + :environment => fast_create(Environment), | ||
105 | + :person => fast_create(Person), | ||
106 | + :enabled => true | ||
107 | + ) | ||
108 | + assert_difference 'NewsletterPlugin::NewsletterMailing.count' do | ||
109 | + NewsletterPlugin.compile_and_send_newsletters | ||
110 | + end | ||
111 | + end | ||
112 | + | ||
113 | +end |
plugins/newsletter/views/newsletter_plugin/mailing_not_found.html.erb
0 → 100644
plugins/newsletter/views/newsletter_plugin/unsubscribe.html.erb
0 → 100644
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +<h1><%= _('Cancel newsletter subscription') %></h1> | ||
2 | + | ||
3 | +<h4> | ||
4 | +<%= _("I don't want to receive future newsletter emails from this network.") %> | ||
5 | +</h4> | ||
6 | + | ||
7 | +<%= _('Send an email to %s requesting your unsubscription or click on the button below.') % link_to(environment.contact_email, "mailto:#{environment.contact_email}?subject=#{_('Cancel newsletter subscription')}") %> | ||
8 | + | ||
9 | +<% button_bar do %> | ||
10 | + <%= button :ok, _('Confirm unsubscription'), {:action => 'confirm_unsubscription'}, :method => 'post' %> | ||
11 | +<% end %> |
plugins/newsletter/views/newsletter_plugin_admin/index.html.erb
0 → 100644
@@ -0,0 +1,92 @@ | @@ -0,0 +1,92 @@ | ||
1 | +<h1><%= _('Newsletter settings') %></h1> | ||
2 | + | ||
3 | +<%= render :file => 'shared/tiny_mce' %> | ||
4 | + | ||
5 | +<%= error_messages_for :newsletter %> | ||
6 | + | ||
7 | +<%= form_for(:newsletter, html: { multipart: true }) do |f| %> | ||
8 | + <%= labelled_form_field( | ||
9 | + content_tag('h3', hidden_field_tag('newsletter[enabled]', false) + | ||
10 | + f.check_box('enabled') + | ||
11 | + _('Enable send of newsletter to members on this environment'), :id => 'newsletter-enabled-field'), | ||
12 | + nil) | ||
13 | + %> | ||
14 | + | ||
15 | + <%= labelled_form_field( | ||
16 | + content_tag('span', hidden_field_tag('newsletter[moderated]', false) + f.check_box('moderated') + _('Moderate newsletter each time before sending to users.')), nil) | ||
17 | + %> | ||
18 | + | ||
19 | + <h2> | ||
20 | + <%= _('Content') %> | ||
21 | + </h2> | ||
22 | + | ||
23 | + <%= labelled_form_field( | ||
24 | + _('Period (in days) for news compilation'), f.number_field(:periodicity, min: '0')) | ||
25 | + %> | ||
26 | + | ||
27 | + <%= labelled_form_field( | ||
28 | + _('Number of posts compiled per blog (choose 0 for all posts since last newsletter)'), f.number_field(:posts_per_blog, min: '0')) | ||
29 | + %> | ||
30 | + | ||
31 | + <p><%= _('Blogs from which news will be compiled') %></p> | ||
32 | + <% search_action = url_for(:action => 'search_communities') %> | ||
33 | + <% selected_blogs = @blogs.map { |blog| {:id => blog.id, :name => _("%s in %s") % [blog.name, blog.profile.name]} } %> | ||
34 | + <%= token_input_field_tag( | ||
35 | + 'newsletter[blog_ids]', 'search-communities', search_action, | ||
36 | + { hint_text: _('Type in the communities\' or blogs\' names'), | ||
37 | + focus: false, pre_populate: selected_blogs }) %> | ||
38 | + | ||
39 | + <br/> | ||
40 | + | ||
41 | + <h2> | ||
42 | + <%= _('Recipients') %> | ||
43 | + </h2> | ||
44 | + | ||
45 | + <p> | ||
46 | + <%= _('You can follow the link below to see which e-mails are currently being used as additional recipients for this newsletter.') %> | ||
47 | + </p> | ||
48 | + <p> | ||
49 | + <%= link_to 'Currently set additional recipients', {action: :recipients}, target: '_blank' %> | ||
50 | + </p> | ||
51 | + | ||
52 | + <p><%= _('You can set additional e-mails to send the newsletter to in addition to all environment\'s users that already receive the newsletter by default. To do that, you need to upload a CSV file that contains a column for the person\'s or enterprise\'s name as well as a column with their e-mail.') %></p> | ||
53 | + | ||
54 | + <%= labelled_form_field( | ||
55 | + _('Additional recipients for newsletter'), file_field_tag('file[recipients]', accept: '.csv')) | ||
56 | + %> | ||
57 | + | ||
58 | + <div id='newsletter-file-options'> | ||
59 | + <%= labelled_form_field( | ||
60 | + content_tag('span', check_box_tag('file[headers]', 1, false, disabled: true) + _('The CSV file contains a header row')), nil) | ||
61 | + %> | ||
62 | + | ||
63 | + <%= labelled_form_field( | ||
64 | + _('Number of colunm with name field'), number_field_tag('file[name]', '1', min: '1', disabled: true)) | ||
65 | + %> | ||
66 | + | ||
67 | + <%= labelled_form_field( | ||
68 | + _('Number of colunm with email field'), number_field_tag('file[email]', '2', min: '1', disabled: true)) | ||
69 | + %> | ||
70 | + </div> | ||
71 | + | ||
72 | + <h2> | ||
73 | + <%= _('Layout') %> | ||
74 | + </h2> | ||
75 | + | ||
76 | + <%= f.fields_for :image_builder, @newsletter.image do |i| %> | ||
77 | + <%= file_field_or_thumbnail(_('Header image (images with 640px width):'), @newsletter.image, i) %> | ||
78 | + <% end %> | ||
79 | + | ||
80 | + <%= labelled_form_field( | ||
81 | + content_tag('h3', ui_icon('ui-icon-triangle-1-s') + | ||
82 | + _('Newsletter footer'), :class => 'newsletter-toggle-link', :element_id => '#newsletter-footer-field'), | ||
83 | + content_tag('div', | ||
84 | + f.text_area(:footer, :style => 'width: 100%', :class => 'mceEditor'), | ||
85 | + :id => 'newsletter-footer-field' | ||
86 | + )) | ||
87 | + %> | ||
88 | + <% button_bar do %> | ||
89 | + <%= submit_button :save, _('Save') %> | ||
90 | + <%= submit_button :save, _('Save and visualize'), :name => "visualize", :cancel => {:controller => 'plugins'} %> | ||
91 | + <% end %> | ||
92 | +<% end %> |
plugins/newsletter/views/newsletter_plugin_admin/recipients.html.erb
0 → 100644
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +<h1><%= _('Additional recipients') %></h1> | ||
2 | + | ||
3 | +<% if @additional_recipients.present? %> | ||
4 | + <table border="0" cellspacing="5" cellpadding="5"> | ||
5 | + <tr> | ||
6 | + <th><%= _('Name') %></th> | ||
7 | + <th><%= _('E-mail') %></th> | ||
8 | + </tr> | ||
9 | + <% @additional_recipients.each do |recipient| %> | ||
10 | + <tr> | ||
11 | + <td><%= recipient[:name] %></td> | ||
12 | + <td><%= recipient[:email] %></td> | ||
13 | + </tr> | ||
14 | + <% end %> | ||
15 | + </table> | ||
16 | +<% else %> | ||
17 | + <p><%= _('There are no additional recipients.') %></p> | ||
18 | +<% end %> | ||
19 | + | ||
20 | +<br/> | ||
21 | +<%= button :back, _('Back'), action: :index %> |
plugins/newsletter/views/tasks/newsletter_plugin/_moderate_newsletter_accept_details.html.erb
0 → 100644
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +<% newsletter = NewsletterPlugin::Newsletter.find(task.newsletter_id) %> | ||
2 | + | ||
3 | +<h1><%= _('Check posts you want to include') %></h1> | ||
4 | + | ||
5 | +<div id='newsletter-moderation-preview'> | ||
6 | + <% newsletter_content = newsletter.body.gsub(/width: 640px;/,'').sub(/#{NewsletterPlugin::Newsletter::CSS['breaking-news-wrap']}/, '') %> | ||
7 | + | ||
8 | + <% newsletter.posts.each do |post| %> | ||
9 | + <% input_name = "tasks[#{task.id}][task][post_ids][]" %> | ||
10 | + <% post_check_box = hidden_field_tag(input_name, '0') +check_box_tag(input_name, post.id, true) %> | ||
11 | + | ||
12 | + <% newsletter_content.gsub!(/<span id="#{post.id}"/, post_check_box+ '<span') %> | ||
13 | + <% newsletter_content.gsub!(/<img id="#{post.id}"/, post_check_box+ '<img') %> | ||
14 | + <% end %> | ||
15 | + | ||
16 | + <%= newsletter_content %> | ||
17 | +</div> |
plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb
@@ -12,7 +12,7 @@ class OrganizationRatingsPluginProfileController < ProfileController | @@ -12,7 +12,7 @@ class OrganizationRatingsPluginProfileController < ProfileController | ||
12 | if @rating_available | 12 | if @rating_available |
13 | create_new_rate | 13 | create_new_rate |
14 | else | 14 | else |
15 | - session[:notice] = _("You can not vote on this %s") % profile.class.name | 15 | + session[:notice] = _("You can not vote on this %s") % _(profile.class.name) |
16 | end | 16 | end |
17 | end | 17 | end |
18 | end | 18 | end |
plugins/organization_ratings/lib/create_organization_rating_comment.rb
@@ -63,7 +63,7 @@ class CreateOrganizationRatingComment < Task | @@ -63,7 +63,7 @@ class CreateOrganizationRatingComment < Task | ||
63 | 63 | ||
64 | def information | 64 | def information |
65 | message = _("<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this %{target_class}") % | 65 | message = _("<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this %{target_class}") % |
66 | - {:requestor_url => url_for(self.requestor.url), :requestor => self.requestor.name, :target_class => self.target.class.name.downcase} | 66 | + {:requestor_url => url_for(self.requestor.url), :requestor => self.requestor.name, :target_class => _(self.target.class.name)} |
67 | 67 | ||
68 | {:message => message} | 68 | {:message => message} |
69 | end | 69 | end |
@@ -88,20 +88,20 @@ class CreateOrganizationRatingComment < Task | @@ -88,20 +88,20 @@ class CreateOrganizationRatingComment < Task | ||
88 | 88 | ||
89 | def target_notification_description | 89 | def target_notification_description |
90 | _("%{requestor} wants to create a comment in this \"%{target}\"") % | 90 | _("%{requestor} wants to create a comment in this \"%{target}\"") % |
91 | - {:requestor => self.requestor.name, :target => self.target.class.name.downcase } | 91 | + {:requestor => self.requestor.name, :target => _(self.target.class.name.downcase) } |
92 | end | 92 | end |
93 | 93 | ||
94 | def target_notification_message | 94 | def target_notification_message |
95 | - _("User \"%{user}\" just requested to create a comment in the %{target_class} | 95 | + _("User \"%{user}\" requested to create a comment in the %{target_class} |
96 | \"%{target_name}\". | 96 | \"%{target_name}\". |
97 | You have to approve or reject it through the \"Pending Validations\" | 97 | You have to approve or reject it through the \"Pending Validations\" |
98 | section in your control panel.\n") % | 98 | section in your control panel.\n") % |
99 | - { :user => self.requestor.name, :target_class => self.target.class.name.downcase, :target_name => self.target.name } | 99 | + { :user => self.requestor.name, :target_class => _(self.target.class.name.downcase), :target_name => self.target.name } |
100 | end | 100 | end |
101 | 101 | ||
102 | def task_created_message | 102 | def task_created_message |
103 | _("Your request for commenting at %{target} was | 103 | _("Your request for commenting at %{target} was |
104 | - just sent. Environment administrator will receive it and will approve or | 104 | + just sent. The administrator will receive it and will approve or |
105 | reject your request according to his methods and criteria. | 105 | reject your request according to his methods and criteria. |
106 | You will be notified as soon as environment administrator has a position | 106 | You will be notified as soon as environment administrator has a position |
107 | about your request.") % | 107 | about your request.") % |
@@ -110,16 +110,16 @@ class CreateOrganizationRatingComment < Task | @@ -110,16 +110,16 @@ class CreateOrganizationRatingComment < Task | ||
110 | 110 | ||
111 | def task_cancelled_message | 111 | def task_cancelled_message |
112 | _("Your request for commenting at %{target} was | 112 | _("Your request for commenting at %{target} was |
113 | - not approved by the environment administrator. The following explanation | 113 | + not approved by the administrator. The following explanation |
114 | was given: \n\n%{explanation}") % | 114 | was given: \n\n%{explanation}") % |
115 | { :target => self.target.name, | 115 | { :target => self.target.name, |
116 | :explanation => self.reject_explanation } | 116 | :explanation => self.reject_explanation } |
117 | end | 117 | end |
118 | 118 | ||
119 | def task_finished_message | 119 | def task_finished_message |
120 | - _('Your request for commenting was approved. | 120 | + _('Your request for commenting at %{target} was approved. |
121 | You can access %{url} to see your comment.') % | 121 | You can access %{url} to see your comment.') % |
122 | - { :url => ratings_url } | 122 | + { :target => self.target.name, :url => ratings_url } |
123 | end | 123 | end |
124 | 124 | ||
125 | private | 125 | private |
plugins/organization_ratings/lib/organization_ratings_block.rb
@@ -6,7 +6,7 @@ class OrganizationRatingsBlock < Block | @@ -6,7 +6,7 @@ class OrganizationRatingsBlock < Block | ||
6 | end | 6 | end |
7 | 7 | ||
8 | def help | 8 | def help |
9 | - _('This block displays the community ratings.') | 9 | + _('This block displays the organization ratings.') |
10 | end | 10 | end |
11 | 11 | ||
12 | def content(args = {}) | 12 | def content(args = {}) |
plugins/organization_ratings/po/organization_ratings.pot
0 → 100644
@@ -0,0 +1,250 @@ | @@ -0,0 +1,250 @@ | ||
1 | +# SOME DESCRIPTIVE TITLE. | ||
2 | +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | ||
3 | +# This file is distributed under the same license as the PACKAGE package. | ||
4 | +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | ||
5 | +# | ||
6 | +#, fuzzy | ||
7 | +msgid "" | ||
8 | +msgstr "" | ||
9 | +"Project-Id-Version: 1.2-478-gee4ad04\n" | ||
10 | +"POT-Creation-Date: 2015-09-11 18:11-0300\n" | ||
11 | +"PO-Revision-Date: 2015-09-11 18:56-0000\n" | ||
12 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||
13 | +"Language-Team: LANGUAGE <LL@li.org>\n" | ||
14 | +"Language: \n" | ||
15 | +"MIME-Version: 1.0\n" | ||
16 | +"Content-Type: text/plain; charset=UTF-8\n" | ||
17 | +"Content-Transfer-Encoding: 8bit\n" | ||
18 | +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | ||
19 | + | ||
20 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:31 | ||
21 | +msgid "Comment waiting for approval" | ||
22 | +msgstr "" | ||
23 | + | ||
24 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:48 | ||
25 | +msgid "Comment rejected" | ||
26 | +msgstr "" | ||
27 | + | ||
28 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:52 | ||
29 | +#: plugins/organization_ratings/views/shared/_user_rating_container.html.erb:28 | ||
30 | +msgid "No comment" | ||
31 | +msgstr "" | ||
32 | + | ||
33 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:61 | ||
34 | +msgid "New Comment" | ||
35 | +msgstr "" | ||
36 | + | ||
37 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:65 | ||
38 | +msgid "" | ||
39 | +"<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this " | ||
40 | +"%{target_class}" | ||
41 | +msgstr "" | ||
42 | + | ||
43 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:90 | ||
44 | +msgid "%{requestor} wants to create a comment in this \"%{target}\"" | ||
45 | +msgstr "" | ||
46 | + | ||
47 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:95 | ||
48 | +msgid "" | ||
49 | +"User \"%{user}\" requested to create a comment in the %{target_class}\n" | ||
50 | +" \"%{target_name}\".\n" | ||
51 | +" You have to approve or reject it through the \"Pending Validations\"\n" | ||
52 | +" section in your control panel.\n" | ||
53 | +msgstr "" | ||
54 | + | ||
55 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:103 | ||
56 | +msgid "" | ||
57 | +"Your request for commenting at %{target} was\n" | ||
58 | +" just sent. The administrator will receive it and will approve or\n" | ||
59 | +" reject your request according to his methods and criteria.\n" | ||
60 | +" You will be notified as soon as environment administrator has a " | ||
61 | +"position\n" | ||
62 | +" about your request." | ||
63 | +msgstr "" | ||
64 | + | ||
65 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:112 | ||
66 | +msgid "" | ||
67 | +"Your request for commenting at %{target} was\n" | ||
68 | +" not approved by the administrator. The following explanation\n" | ||
69 | +" was given: \n" | ||
70 | +"\n" | ||
71 | +"%{explanation}" | ||
72 | +msgstr "" | ||
73 | + | ||
74 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:120 | ||
75 | +msgid "" | ||
76 | +"Your request for commenting at %{target} was approved.\n" | ||
77 | +" You can access %{url} to see your comment." | ||
78 | +msgstr "" | ||
79 | + | ||
80 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | ||
81 | +msgid "More Recent" | ||
82 | +msgstr "" | ||
83 | + | ||
84 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | ||
85 | +msgid "Best Ratings" | ||
86 | +msgstr "" | ||
87 | + | ||
88 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:5 | ||
89 | +msgid "Organization Ratings" | ||
90 | +msgstr "" | ||
91 | + | ||
92 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:9 | ||
93 | +msgid "This block displays the organization ratings." | ||
94 | +msgstr "" | ||
95 | + | ||
96 | +#: plugins/organization_ratings/lib/average_rating_block.rb:5 | ||
97 | +msgid "Organization Average Rating" | ||
98 | +msgstr "" | ||
99 | + | ||
100 | +#: plugins/organization_ratings/lib/average_rating_block.rb:9 | ||
101 | +msgid "This block displays the organization average rating." | ||
102 | +msgstr "" | ||
103 | + | ||
104 | +#: plugins/organization_ratings/lib/organization_ratings_plugin.rb:9 | ||
105 | +msgid "A plugin that allows you to rate a organization and comment about it." | ||
106 | +msgstr "" | ||
107 | + | ||
108 | +#: plugins/organization_ratings/lib/organization_rating.rb:10 | ||
109 | +msgid "must be between 1 and 5" | ||
110 | +msgstr "" | ||
111 | + | ||
112 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:12 | ||
113 | +msgid "Configuration updated successfully." | ||
114 | +msgstr "" | ||
115 | + | ||
116 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:14 | ||
117 | +msgid "Configuration could not be saved." | ||
118 | +msgstr "" | ||
119 | + | ||
120 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:15 | ||
121 | +msgid "You can not vote on this %s" | ||
122 | +msgstr "" | ||
123 | + | ||
124 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:47 | ||
125 | +msgid "%s successfully rated!" | ||
126 | +msgstr "" | ||
127 | + | ||
128 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:49 | ||
129 | +msgid "Sorry, there were problems rating this profile." | ||
130 | +msgstr "" | ||
131 | + | ||
132 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:11 | ||
133 | +msgid "User not logged" | ||
134 | +msgstr "" | ||
135 | + | ||
136 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:17 | ||
137 | +msgid "Report your experiences." | ||
138 | +msgstr "" | ||
139 | + | ||
140 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:24 | ||
141 | +msgid "* You must be logged in to submit a report." | ||
142 | +msgstr "" | ||
143 | + | ||
144 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:3 | ||
145 | +msgid "Rate %s " | ||
146 | +msgstr "" | ||
147 | + | ||
148 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:7 | ||
149 | +msgid "Log in" | ||
150 | +msgstr "" | ||
151 | + | ||
152 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:3 | ||
153 | +msgid "Organization Rating Settings" | ||
154 | +msgstr "" | ||
155 | + | ||
156 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:10 | ||
157 | +msgid "Value" | ||
158 | +msgstr "" | ||
159 | + | ||
160 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:13 | ||
161 | +msgid "Default amount of stars marked on evaluations" | ||
162 | +msgstr "" | ||
163 | + | ||
164 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:17 | ||
165 | +msgid "Users can rate an organization only once" | ||
166 | +msgstr "" | ||
167 | + | ||
168 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:21 | ||
169 | +msgid "The comments are moderated" | ||
170 | +msgstr "" | ||
171 | + | ||
172 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:26 | ||
173 | +msgid "Time in hours between evaluations from the same user." | ||
174 | +msgstr "" | ||
175 | + | ||
176 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:27 | ||
177 | +msgid "To disable cooldown use zero (0) value." | ||
178 | +msgstr "" | ||
179 | + | ||
180 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:35 | ||
181 | +msgid "Order ratings by" | ||
182 | +msgstr "" | ||
183 | + | ||
184 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:41 | ||
185 | +msgid "Ratings amount per page" | ||
186 | +msgstr "" | ||
187 | + | ||
188 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:50 | ||
189 | +msgid "Back" | ||
190 | +msgstr "" | ||
191 | + | ||
192 | +#: plugins/organization_ratings/views/tasks/_create_organization_rating_comment_accept_details.html.erb:2 | ||
193 | +msgid "Comment:" | ||
194 | +msgstr "" | ||
195 | + | ||
196 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | ||
197 | +msgid "Rated as" | ||
198 | +msgstr "" | ||
199 | + | ||
200 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | ||
201 | +msgid "stars" | ||
202 | +msgstr "" | ||
203 | + | ||
204 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:46 | ||
205 | +msgid "Comment (Optional):" | ||
206 | +msgstr "" | ||
207 | + | ||
208 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:53 | ||
209 | +msgid "Save" | ||
210 | +msgstr "" | ||
211 | + | ||
212 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:63 | ||
213 | +msgid "Hi, %s! The administrators set that you can vote" | ||
214 | +msgstr "" | ||
215 | + | ||
216 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:64 | ||
217 | +msgid "only once" | ||
218 | +msgstr "" | ||
219 | + | ||
220 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:65 | ||
221 | +msgid "for this %s." | ||
222 | +msgstr "" | ||
223 | + | ||
224 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:70 | ||
225 | +msgid "Hi, %s! The administrators set the minimum time of" | ||
226 | +msgstr "" | ||
227 | + | ||
228 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:71 | ||
229 | +msgid "%s hour(s)" | ||
230 | +msgstr "" | ||
231 | + | ||
232 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:72 | ||
233 | +msgid "between each evaluation." | ||
234 | +msgstr "" | ||
235 | + | ||
236 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:4 | ||
237 | +msgid "Rating: " | ||
238 | +msgstr "" | ||
239 | + | ||
240 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:18 | ||
241 | +msgid "Be the first to rate!" | ||
242 | +msgstr "" | ||
243 | + | ||
244 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:23 | ||
245 | +msgid "Rate this %s" | ||
246 | +msgstr "" | ||
247 | + | ||
248 | +#: plugins/organization_ratings/views/blocks/organization_ratings_block.html.erb:17 | ||
249 | +msgid "See more" | ||
250 | +msgstr "" |
plugins/organization_ratings/po/pt/organization_ratings.po
0 → 100644
@@ -0,0 +1,274 @@ | @@ -0,0 +1,274 @@ | ||
1 | +# SOME DESCRIPTIVE TITLE. | ||
2 | +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | ||
3 | +# This file is distributed under the same license as the PACKAGE package. | ||
4 | +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | ||
5 | +# | ||
6 | +#, fuzzy | ||
7 | +msgid "" | ||
8 | +msgstr "" | ||
9 | +"Project-Id-Version: 1.2-478-gee4ad04\n" | ||
10 | +"POT-Creation-Date: 2015-09-11 18:11-0300\n" | ||
11 | +"PO-Revision-Date: 2015-09-11 18:56-0000\n" | ||
12 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||
13 | +"Language-Team: LANGUAGE <LL@li.org>\n" | ||
14 | +"Language: \n" | ||
15 | +"MIME-Version: 1.0\n" | ||
16 | +"Content-Type: text/plain; charset=UTF-8\n" | ||
17 | +"Content-Transfer-Encoding: 8bit\n" | ||
18 | +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | ||
19 | + | ||
20 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:31 | ||
21 | +msgid "Comment waiting for approval" | ||
22 | +msgstr "Comentario aguardando aprovação" | ||
23 | + | ||
24 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:48 | ||
25 | +msgid "Comment rejected" | ||
26 | +msgstr "Comentário rejeitado" | ||
27 | + | ||
28 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:52 | ||
29 | +#: plugins/organization_ratings/views/shared/_user_rating_container.html.erb:28 | ||
30 | +msgid "No comment" | ||
31 | +msgstr "Sem comentário" | ||
32 | + | ||
33 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:61 | ||
34 | +msgid "New Comment" | ||
35 | +msgstr "Novo Comentário" | ||
36 | + | ||
37 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:65 | ||
38 | +msgid "" | ||
39 | +"<a href=%{requestor_url}>%{requestor}</a> wants to create a comment in this " | ||
40 | +"%{target_class}" | ||
41 | +msgstr "" | ||
42 | +"<a href=%{requestor_url}>%{requestor}</a> deseja criar um comentário " | ||
43 | +"neste(a) %{target_class}" | ||
44 | + | ||
45 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:90 | ||
46 | +msgid "%{requestor} wants to create a comment in this \"%{target}\"" | ||
47 | +msgstr "%{requestor} deseja criar um comentário neste(a) \"%{target}\"" | ||
48 | + | ||
49 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:95 | ||
50 | +msgid "" | ||
51 | +"User \"%{user}\" requested to create a comment in the %{target_class}\n" | ||
52 | +" \"%{target_name}\".\n" | ||
53 | +" You have to approve or reject it through the \"Pending Validations\"\n" | ||
54 | +" section in your control panel.\n" | ||
55 | +msgstr "" | ||
56 | +"O usuário \"%{user}\" requisitou a criação de um comentário na " | ||
57 | +"%{target_class}\n" | ||
58 | +" \"%{target_name}\".\n" | ||
59 | +" Você deve aprová-lo ou rejeitá-lo através da seção de \"Validações " | ||
60 | +"Pendentes\"\n" | ||
61 | +" no seu painel de controle.\n" | ||
62 | + | ||
63 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:103 | ||
64 | +msgid "" | ||
65 | +"Your request for commenting at %{target} was\n" | ||
66 | +" just sent. The administrator will receive it and will approve or\n" | ||
67 | +" reject your request according to his methods and criteria.\n" | ||
68 | +" You will be notified as soon as environment administrator has a " | ||
69 | +"position\n" | ||
70 | +" about your request." | ||
71 | +msgstr "" | ||
72 | +"Seu pedido para comentar em %{target} foi\n" | ||
73 | +" enviado. O administrador irá recebê-lo e aprovarou\n" | ||
74 | +" rejeitar seu pedido de acordo com seus métodos e critérios.\n" | ||
75 | +" Você será notificado assim que o administrador tenha umaposição\n" | ||
76 | +" sobre seu pedido." | ||
77 | + | ||
78 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:112 | ||
79 | +msgid "" | ||
80 | +"Your request for commenting at %{target} was\n" | ||
81 | +" not approved by the administrator. The following explanation\n" | ||
82 | +" was given: \n" | ||
83 | +"\n" | ||
84 | +"%{explanation}" | ||
85 | +msgstr "" | ||
86 | +"Seu pedido para comentar em %{target} não\n" | ||
87 | +" foi aprovado pelo administrador. A seguinte explicação\n" | ||
88 | +" foi dada: \n" | ||
89 | +"\n" | ||
90 | +"%{explanation}" | ||
91 | + | ||
92 | +#: plugins/organization_ratings/lib/create_organization_rating_comment.rb:120 | ||
93 | +msgid "" | ||
94 | +"Your request for commenting at %{target} was approved.\n" | ||
95 | +" You can access %{url} to see your comment." | ||
96 | +msgstr "" | ||
97 | +"Seu pedido para comentar em %{target} foi aprovado.\n" | ||
98 | +"\tVocê pode acessar %{url} para ver seu comentário." | ||
99 | + | ||
100 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | ||
101 | +msgid "More Recent" | ||
102 | +msgstr "Mais Recentes" | ||
103 | + | ||
104 | +#: plugins/organization_ratings/lib/organization_ratings_config.rb:8 | ||
105 | +msgid "Best Ratings" | ||
106 | +msgstr "Melhores Avaliações" | ||
107 | + | ||
108 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:5 | ||
109 | +msgid "Organization Ratings" | ||
110 | +msgstr "Avaliações da Organização" | ||
111 | + | ||
112 | +#: plugins/organization_ratings/lib/organization_ratings_block.rb:9 | ||
113 | +msgid "This block displays the organization ratings." | ||
114 | +msgstr "Este bloco mostra as avaliações da organização." | ||
115 | + | ||
116 | +#: plugins/organization_ratings/lib/average_rating_block.rb:5 | ||
117 | +msgid "Organization Average Rating" | ||
118 | +msgstr "Média de Avaliações da Organização" | ||
119 | + | ||
120 | +#: plugins/organization_ratings/lib/average_rating_block.rb:9 | ||
121 | +msgid "This block displays the organization average rating." | ||
122 | +msgstr "Este bloco mostra a média de avaliações da organização." | ||
123 | + | ||
124 | +#: plugins/organization_ratings/lib/organization_ratings_plugin.rb:9 | ||
125 | +msgid "A plugin that allows you to rate a organization and comment about it." | ||
126 | +msgstr "" | ||
127 | +"Um plugin que permite que você avalie uma organização e comente sobre ela." | ||
128 | + | ||
129 | +#: plugins/organization_ratings/lib/organization_rating.rb:10 | ||
130 | +msgid "must be between 1 and 5" | ||
131 | +msgstr "deve ser entre 1 e 5" | ||
132 | + | ||
133 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:12 | ||
134 | +msgid "Configuration updated successfully." | ||
135 | +msgstr "Configurações atualizadas com sucesso." | ||
136 | + | ||
137 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_admin_controller.rb:14 | ||
138 | +msgid "Configuration could not be saved." | ||
139 | +msgstr "Configurações não puderam ser salvas." | ||
140 | + | ||
141 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:15 | ||
142 | +msgid "You can not vote on this %s" | ||
143 | +msgstr "Você não pode votar nesta %s" | ||
144 | + | ||
145 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:47 | ||
146 | +msgid "%s successfully rated!" | ||
147 | +msgstr "%s avaliada com sucesso!" | ||
148 | + | ||
149 | +#: plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb:49 | ||
150 | +msgid "Sorry, there were problems rating this profile." | ||
151 | +msgstr "Desculpe, ocorreram problemas na avaliação deste perfil." | ||
152 | + | ||
153 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:11 | ||
154 | +msgid "User not logged" | ||
155 | +msgstr "Usuário não logado" | ||
156 | + | ||
157 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:17 | ||
158 | +msgid "Report your experiences." | ||
159 | +msgstr "Relate suas experiências." | ||
160 | + | ||
161 | +#: plugins/organization_ratings/views/shared/_make_report_block.html.erb:24 | ||
162 | +msgid "* You must be logged in to submit a report." | ||
163 | +msgstr "* Você precisa estar logado para enviar um relato." | ||
164 | + | ||
165 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:3 | ||
166 | +msgid "Rate %s " | ||
167 | +msgstr "Avaliar %s " | ||
168 | + | ||
169 | +#: plugins/organization_ratings/views/shared/_rating_button.html.erb:7 | ||
170 | +msgid "Log in" | ||
171 | +msgstr "Entrar" | ||
172 | + | ||
173 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:3 | ||
174 | +msgid "Organization Rating Settings" | ||
175 | +msgstr "Configuração para Avaliações em Organizações" | ||
176 | + | ||
177 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:10 | ||
178 | +msgid "Value" | ||
179 | +msgstr "Valor" | ||
180 | + | ||
181 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:13 | ||
182 | +msgid "Default amount of stars marked on evaluations" | ||
183 | +msgstr "Quantidade padrão de estrelas marcadas nas avaliações" | ||
184 | + | ||
185 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:17 | ||
186 | +msgid "Users can rate an organization only once" | ||
187 | +msgstr "Usuários podem avaliar uma organização apenas uma vez" | ||
188 | + | ||
189 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:21 | ||
190 | +msgid "The comments are moderated" | ||
191 | +msgstr "Os comentários são moderados" | ||
192 | + | ||
193 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:26 | ||
194 | +msgid "Time in hours between evaluations from the same user." | ||
195 | +msgstr "Tempo em horas entre avaliações do mesmo usuário." | ||
196 | + | ||
197 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:27 | ||
198 | +msgid "To disable cooldown use zero (0) value." | ||
199 | +msgstr "Bara desabilitar o tempo de espera utilize o valor zero (0)." | ||
200 | + | ||
201 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:35 | ||
202 | +msgid "Order ratings by" | ||
203 | +msgstr "Ordenar avaliações por" | ||
204 | + | ||
205 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:41 | ||
206 | +msgid "Ratings amount per page" | ||
207 | +msgstr "Quantidade de avaliações por página" | ||
208 | + | ||
209 | +#: plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb:50 | ||
210 | +msgid "Back" | ||
211 | +msgstr "Voltar" | ||
212 | + | ||
213 | +#: plugins/organization_ratings/views/tasks/_create_organization_rating_comment_accept_details.html.erb:2 | ||
214 | +msgid "Comment:" | ||
215 | +msgstr "Comentário:" | ||
216 | + | ||
217 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | ||
218 | +msgid "Rated as" | ||
219 | +msgstr "Avaliado em" | ||
220 | + | ||
221 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:39 | ||
222 | +msgid "stars" | ||
223 | +msgstr "estrelas" | ||
224 | + | ||
225 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:46 | ||
226 | +msgid "Comment (Optional):" | ||
227 | +msgstr "Comentário (Opcional):" | ||
228 | + | ||
229 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:53 | ||
230 | +msgid "Save" | ||
231 | +msgstr "Salvar" | ||
232 | + | ||
233 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:63 | ||
234 | +msgid "Hi, %s! The administrators set that you can vote" | ||
235 | +msgstr "Olá, %s! Os administradores configuraram que você pode votar apenas" | ||
236 | + | ||
237 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:64 | ||
238 | +msgid "only once" | ||
239 | +msgstr "uma vez" | ||
240 | + | ||
241 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:65 | ||
242 | +msgid "for this %s." | ||
243 | +msgstr "para esta %s." | ||
244 | + | ||
245 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:70 | ||
246 | +msgid "Hi, %s! The administrators set the minimum time of" | ||
247 | +msgstr "Olá, %s! Os administradores configuraram o tempo mínimo de " | ||
248 | + | ||
249 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:71 | ||
250 | +msgid "%s hour(s)" | ||
251 | +msgstr "%s hora(s)" | ||
252 | + | ||
253 | +#: plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb:72 | ||
254 | +msgid "between each evaluation." | ||
255 | +msgstr "entre cada avaliação." | ||
256 | + | ||
257 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:4 | ||
258 | +msgid "Rating: " | ||
259 | +msgstr "Avaliação:" | ||
260 | + | ||
261 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:18 | ||
262 | +msgid "Be the first to rate!" | ||
263 | +msgstr "Seja o primeiro a avaliar!" | ||
264 | + | ||
265 | +#: plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb:23 | ||
266 | +msgid "Rate this %s" | ||
267 | +msgstr "Avalie esta %s" | ||
268 | + | ||
269 | +#: plugins/organization_ratings/views/blocks/organization_ratings_block.html.erb:17 | ||
270 | +msgid "See more" | ||
271 | +msgstr "Veja mais" | ||
272 | + | ||
273 | +#~ msgid "community" | ||
274 | +#~ msgstr "comunidade" |
plugins/organization_ratings/views/blocks/display_organization_average_rating.html.erb
@@ -20,6 +20,6 @@ | @@ -20,6 +20,6 @@ | ||
20 | <% end %> | 20 | <% end %> |
21 | 21 | ||
22 | <div class="rate-this-organization"> | 22 | <div class="rate-this-organization"> |
23 | - <%= link_to _("Rate this %s" % profile.class.name), url_for(:controller => "organization_ratings_plugin_profile", :action => "new_rating", :profile=>profile_identifier) %> | 23 | + <%= link_to _("Rate this %s" % _(profile.class.name)), url_for(:controller => "organization_ratings_plugin_profile", :action => "new_rating", :profile=>profile_identifier) %> |
24 | </div> | 24 | </div> |
25 | </div> | 25 | </div> |
26 | \ No newline at end of file | 26 | \ No newline at end of file |
plugins/organization_ratings/views/organization_ratings_plugin_admin/index.html.erb
1 | <% config = env_organization_ratings_config %> | 1 | <% config = env_organization_ratings_config %> |
2 | 2 | ||
3 | -<h1><%= _("Organization Rating Management") %> </h1> | 3 | +<h1><%= _("Organization Rating Settings") %> </h1> |
4 | 4 | ||
5 | <%= labelled_form_for(:organization_ratings_config, :url => {:action => 'update'}) do |f| %> | 5 | <%= labelled_form_for(:organization_ratings_config, :url => {:action => 'update'}) do |f| %> |
6 | <%= labelled_fields_for(:organization_ratings_config, config) do |c| %> | 6 | <%= labelled_fields_for(:organization_ratings_config, config) do |c| %> |
@@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
14 | <td><%= c.select :default_rating, (config.minimum_ratings)..5 %></td> | 14 | <td><%= c.select :default_rating, (config.minimum_ratings)..5 %></td> |
15 | </tr> | 15 | </tr> |
16 | <tr> | 16 | <tr> |
17 | - <td><%= _('Can rate an organization only once') %></td> | 17 | + <td><%= _('Users can rate an organization only once') %></td> |
18 | <td><%= c.check_box :vote_once %></td> | 18 | <td><%= c.check_box :vote_once %></td> |
19 | </tr> | 19 | </tr> |
20 | <tr> | 20 | <tr> |
@@ -38,7 +38,7 @@ | @@ -38,7 +38,7 @@ | ||
38 | <td><%= c.select :order, order_options %></td> | 38 | <td><%= c.select :order, order_options %></td> |
39 | </tr> | 39 | </tr> |
40 | <tr> | 40 | <tr> |
41 | - <td><%= _('Ratings per page') %></td> | 41 | + <td><%= _('Ratings amount per page') %></td> |
42 | <td> | 42 | <td> |
43 | <%= c.select :per_page, 5..20 %> | 43 | <%= c.select :per_page, 5..20 %> |
44 | </td> | 44 | </td> |
plugins/organization_ratings/views/shared/_make_report_block.html.erb
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | </div> | 8 | </div> |
9 | 9 | ||
10 | <div class="star-profile-name"> | 10 | <div class="star-profile-name"> |
11 | - <%= logged_in? ? current_user.person.name : _('User not logged *') %> | 11 | + <%= logged_in? ? current_user.person.name : _('User not logged') %> |
12 | </div> | 12 | </div> |
13 | </div> | 13 | </div> |
14 | 14 |
plugins/organization_ratings/views/shared/_rating_button.html.erb
1 | <% button_bar do %> | 1 | <% button_bar do %> |
2 | <% if logged_in? %> | 2 | <% if logged_in? %> |
3 | - <%= button(:new,_("Rate %s ") % profile.class.name, | 3 | + <%= button(:new,_("Rate %s ") % _(profile.class.name), |
4 | {:controller => "organization_ratings_plugin_profile", | 4 | {:controller => "organization_ratings_plugin_profile", |
5 | :action => "new_rating"}) %> | 5 | :action => "new_rating"}) %> |
6 | <% else %> | 6 | <% else %> |
script/quick-start
@@ -122,6 +122,7 @@ fi | @@ -122,6 +122,7 @@ fi | ||
122 | 122 | ||
123 | # create needed directory | 123 | # create needed directory |
124 | mkdir -p tmp/pids | 124 | mkdir -p tmp/pids |
125 | +mkdir -p tmp/cache | ||
125 | 126 | ||
126 | # use default gitignore rules | 127 | # use default gitignore rules |
127 | if [ ! -f .gitignore ]; then | 128 | if [ ! -f .gitignore ]; then |
script/sample-articles
@@ -65,3 +65,22 @@ for subject in EVENT_SUBJECTS | @@ -65,3 +65,22 @@ for subject in EVENT_SUBJECTS | ||
65 | end | 65 | end |
66 | end | 66 | end |
67 | done | 67 | done |
68 | + | ||
69 | +print "Creating some posts: " | ||
70 | +for subject in SUBJECTS | ||
71 | + rand(20).times do |i| | ||
72 | + profile = profiles.sample | ||
73 | + name = "%s #{subject}" % profile.name | ||
74 | + article = TinyMceArticle.new( | ||
75 | + :name => name, | ||
76 | + :body => name, | ||
77 | + :tag_list => [TAGS.sample, TAGS.sample], | ||
78 | + :profile => profile, | ||
79 | + :parent_id => profile.blog.id | ||
80 | + ) | ||
81 | + save article do | ||
82 | + article.add_category categories.sample | ||
83 | + end | ||
84 | + end | ||
85 | +end | ||
86 | +done |
util/debian-install/install
@@ -93,7 +93,7 @@ fi | @@ -93,7 +93,7 @@ fi | ||
93 | 93 | ||
94 | apt-get update | 94 | apt-get update |
95 | apt-get dist-upgrade -qy | 95 | apt-get dist-upgrade -qy |
96 | -apt-get install -qy postgresql | 96 | +apt-get install -qy postgresql postfix |
97 | 97 | ||
98 | apt-cache policy noosfero | 98 | apt-cache policy noosfero |
99 | apt-get install -qy noosfero noosfero-apache | 99 | apt-get install -qy noosfero noosfero-apache |