Commit fd23e87459ed5131a3270fcaaa0a4bc0ead1d8d2
Committed by
Daniela Feitosa
1 parent
ba117529
Exists in
master
and in
22 other branches
curriculum_lattes_plugin: Refactorign plugin structure
- Indent files properly - Fix signup page changing lambda to proc - Create the needed plugin's hotspots - Fix academic_info attributes update - Fix hotspot to work in edit page
Showing
16 changed files
with
219 additions
and
95 deletions
Show diff stats
app/controllers/admin/features_controller.rb
@@ -17,6 +17,10 @@ class FeaturesController < AdminController | @@ -17,6 +17,10 @@ class FeaturesController < AdminController | ||
17 | 17 | ||
18 | def manage_fields | 18 | def manage_fields |
19 | @person_fields = Person.fields | 19 | @person_fields = Person.fields |
20 | + @plugins.dispatch(:extra_person_fields).collect do |field| | ||
21 | + @person_fields << field unless @person_fields.include?(field) | ||
22 | + end | ||
23 | + | ||
20 | @enterprise_fields = Enterprise.fields | 24 | @enterprise_fields = Enterprise.fields |
21 | @community_fields = Community.fields | 25 | @community_fields = Community.fields |
22 | end | 26 | end |
app/controllers/my_profile/profile_editor_controller.rb
@@ -15,14 +15,22 @@ class ProfileEditorController < MyProfileController | @@ -15,14 +15,22 @@ class ProfileEditorController < MyProfileController | ||
15 | @possible_domains = profile.possible_domains | 15 | @possible_domains = profile.possible_domains |
16 | if request.post? | 16 | if request.post? |
17 | params[:profile_data][:fields_privacy] ||= {} if profile.person? && params[:profile_data].is_a?(Hash) | 17 | params[:profile_data][:fields_privacy] ||= {} if profile.person? && params[:profile_data].is_a?(Hash) |
18 | - Profile.transaction do | ||
19 | - Image.transaction do | ||
20 | - if @profile_data.update_attributes(params[:profile_data]) | ||
21 | - redirect_to :action => 'index', :profile => profile.identifier | ||
22 | - else | ||
23 | - profile.identifier = params[:profile] if profile.identifier.blank? | 18 | + begin |
19 | + @plugins.dispatch(:profile_editor_transaction_extras) | ||
20 | + | ||
21 | + Profile.transaction do | ||
22 | + Image.transaction do | ||
23 | + if @profile_data.update_attributes(params[:profile_data]) | ||
24 | + redirect_to :action => 'index', :profile => profile.identifier | ||
25 | + else | ||
26 | + profile.identifier = params[:profile] if profile.identifier.blank? | ||
27 | + end | ||
28 | + end | ||
29 | + end | ||
30 | + rescue Exception => ex | ||
31 | + if profile.identifier.blank? | ||
32 | + profile.identifier = params[:profile] | ||
24 | end | 33 | end |
25 | - end | ||
26 | end | 34 | end |
27 | end | 35 | end |
28 | end | 36 | end |
app/controllers/public/account_controller.rb
@@ -93,7 +93,13 @@ class AccountController < ApplicationController | @@ -93,7 +93,13 @@ class AccountController < ApplicationController | ||
93 | @user.terms_of_use = environment.terms_of_use | 93 | @user.terms_of_use = environment.terms_of_use |
94 | @user.environment = environment | 94 | @user.environment = environment |
95 | @terms_of_use = environment.terms_of_use | 95 | @terms_of_use = environment.terms_of_use |
96 | - @user.person_data = params[:profile_data] | 96 | + |
97 | + params_profile_data = params[:profile_data] | ||
98 | + @plugins.dispatch(:extra_person_data_params).each do |data| | ||
99 | + params_profile_data = params_profile_data.merge(data) unless params[:profile_data].blank? | ||
100 | + end | ||
101 | + | ||
102 | + @user.person_data = params_profile_data | ||
97 | @user.return_to = session[:return_to] | 103 | @user.return_to = session[:return_to] |
98 | @person = Person.new(params[:profile_data]) | 104 | @person = Person.new(params[:profile_data]) |
99 | @person.environment = @user.environment | 105 | @person.environment = @user.environment |
app/models/user.rb
@@ -29,6 +29,8 @@ class User < ActiveRecord::Base | @@ -29,6 +29,8 @@ class User < ActiveRecord::Base | ||
29 | alias_method_chain :human_attribute_name, :customization | 29 | alias_method_chain :human_attribute_name, :customization |
30 | end | 30 | end |
31 | 31 | ||
32 | + include Noosfero::Plugin::HotSpot | ||
33 | + | ||
32 | before_create do |user| | 34 | before_create do |user| |
33 | if user.environment.nil? | 35 | if user.environment.nil? |
34 | user.environment = Environment.default | 36 | user.environment = Environment.default |
@@ -46,6 +48,7 @@ class User < ActiveRecord::Base | @@ -46,6 +48,7 @@ class User < ActiveRecord::Base | ||
46 | p.environment = user.environment | 48 | p.environment = user.environment |
47 | p.name ||= user.name || user.login | 49 | p.name ||= user.name || user.login |
48 | p.visible = false unless user.activated? | 50 | p.visible = false unless user.activated? |
51 | + | ||
49 | p.save! | 52 | p.save! |
50 | 53 | ||
51 | user.person = p | 54 | user.person = p |
app/views/profile_editor/_person_form.html.erb
@@ -27,6 +27,10 @@ | @@ -27,6 +27,10 @@ | ||
27 | <%= optional_field(@person, 'district', labelled_form_field(_('District'), text_field(:profile_data, :district, :rel => _('District')))) %> | 27 | <%= optional_field(@person, 'district', labelled_form_field(_('District'), text_field(:profile_data, :district, :rel => _('District')))) %> |
28 | <%= optional_field(@person, 'image', labelled_form_field(_('Image'), file_field(:file, :image, :rel => _('Image')))) %> | 28 | <%= optional_field(@person, 'image', labelled_form_field(_('Image'), file_field(:file, :image, :rel => _('Image')))) %> |
29 | 29 | ||
30 | +<% @plugins.dispatch(:extra_optional_fields).each do |field| %> | ||
31 | + <%= optional_field(@person, field[:name], labelled_form_field(field[:label], text_field(field[:object_name], field[:method], :rel => field[:label], :value => field[:value]))) %> | ||
32 | +<% end %> | ||
33 | + | ||
30 | <% optional_field(@person, 'schooling') do %> | 34 | <% optional_field(@person, 'schooling') do %> |
31 | <div class="formfieldline"> | 35 | <div class="formfieldline"> |
32 | <label class='formlabel' for='profile_data_schooling'><%= _('Schooling') %></label> | 36 | <label class='formlabel' for='profile_data_schooling'><%= _('Schooling') %></label> |
lib/noosfero/plugin.rb
@@ -531,6 +531,29 @@ class Noosfero::Plugin | @@ -531,6 +531,29 @@ class Noosfero::Plugin | ||
531 | nil | 531 | nil |
532 | end | 532 | end |
533 | 533 | ||
534 | + # -> Perform extra transactions related to profile in profile editor | ||
535 | + # returns = true in success or raise and exception if it could not update the data | ||
536 | + def profile_editor_transaction_extras | ||
537 | + nil | ||
538 | + end | ||
539 | + | ||
540 | + # -> Return a list of extra person fields | ||
541 | + # returns = a list of strings with fields' name | ||
542 | + def extra_person_fields | ||
543 | + [] | ||
544 | + end | ||
545 | + | ||
546 | + # -> Return a list of hashs with the needed information to create optional fields | ||
547 | + # returns = a list of hashs as {:name => "string", :label => "string", :object_name => :key, :method => :key} | ||
548 | + def extra_optional_fields | ||
549 | + [] | ||
550 | + end | ||
551 | + | ||
552 | + # -> Return a hash with another object's params | ||
553 | + def extra_person_data_params | ||
554 | + {} | ||
555 | + end | ||
556 | + | ||
534 | # -> Adds additional blocks to profiles and environments. | 557 | # -> Adds additional blocks to profiles and environments. |
535 | # Your plugin must implements a class method called 'extra_blocks' | 558 | # Your plugin must implements a class method called 'extra_blocks' |
536 | # that returns a hash with the following syntax. | 559 | # that returns a hash with the following syntax. |
plugins/lattes_curriculum/db/migrate/20140415223448_add_url_lattes_to_person.rb
plugins/lattes_curriculum/db/migrate/20140814210103_create_academic_infos.rb
0 → 100644
plugins/lattes_curriculum/features/lattes_curriculum.feature
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +Feature: import lattes information | ||
2 | + As an user | ||
3 | + I want to inform my lattes url address | ||
4 | + So that I can import my academic informations automatically | ||
5 | + | ||
6 | + Background: | ||
7 | + Given "LattesCurriculumPlugin" plugin is enabled | ||
8 | + And I am logged in as admin | ||
9 | + And I go to /admin/plugins | ||
10 | + And I check "LattesCurriculumPlugin" | ||
11 | + And I press "Save changes" | ||
12 | + And I am not logged in | ||
13 | + | ||
14 | + @selenium | ||
15 | + Scenario: Import lattes informations after singup | ||
16 | + Given I am on signup page | ||
17 | + And I fill in "e-Mail" with "josesilva@example.com" | ||
18 | + And I fill in "Username" with "josesilva" | ||
19 | + And I fill in "Full name" with "João Silva" | ||
20 | + And I fill in "Password" with "secret" | ||
21 | + And I fill in "Password confirmation" with "secret" | ||
22 | + And I fill in "URL Lattes" with "http://lattes.cnpq.br/2864976228727880" | ||
23 | + And wait for the captcha signup time | ||
24 | + And I press "Create my account" | ||
0 | \ No newline at end of file | 25 | \ No newline at end of file |
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +class AcademicInfo < ActiveRecord::Base | ||
2 | + | ||
3 | + belongs_to :person | ||
4 | + | ||
5 | + attr_accessible :lattes_url | ||
6 | + validate :lattes_url_validate? | ||
7 | + | ||
8 | + def lattes_url_validate? | ||
9 | + valid_url_start = 'http://lattes.cnpq.br/' | ||
10 | + unless self.lattes_url.blank? || self.lattes_url =~ /http:\/\/lattes.cnpq.br\/\d+/ | ||
11 | + self.errors.add(:lattes_url, _("Sorry, the lattes url is not valid.")) | ||
12 | + end | ||
13 | + end | ||
14 | +end |
plugins/lattes_curriculum/lib/ext/person.rb
@@ -2,14 +2,17 @@ require_dependency 'person' | @@ -2,14 +2,17 @@ require_dependency 'person' | ||
2 | 2 | ||
3 | class Person | 3 | class Person |
4 | 4 | ||
5 | - attr_accessible :lattes_url | ||
6 | - validate :lattes_url_validate? | ||
7 | - | ||
8 | - def lattes_url_validate? | ||
9 | - valid_url_start = 'http://lattes.cnpq.br/' | ||
10 | - unless self.lattes_url =~ /http:\/\/lattes.cnpq.br\/\d+/ | ||
11 | - errors[:base] << "Sorry, the lattes url is not valid." | ||
12 | - end | 5 | + attr_accessible :lattes_url, :academic_info_attributes |
6 | + | ||
7 | + has_one :academic_info, :dependent=>:delete | ||
8 | + | ||
9 | + accepts_nested_attributes_for :academic_info | ||
10 | + | ||
11 | + def lattes_url | ||
12 | + self.academic_info.nil? ? nil : self.academic_info.lattes_url | ||
13 | end | 13 | end |
14 | 14 | ||
15 | -end | ||
16 | \ No newline at end of file | 15 | \ No newline at end of file |
16 | + def lattes_url= value | ||
17 | + self.academic_info.lattes_url = value unless self.academic_info.nil? | ||
18 | + end | ||
19 | +end |
plugins/lattes_curriculum/lib/html_parser.rb
@@ -6,55 +6,57 @@ Encoding.default_external = Encoding::UTF_8 | @@ -6,55 +6,57 @@ Encoding.default_external = Encoding::UTF_8 | ||
6 | Encoding.default_internal = Encoding::UTF_8 | 6 | Encoding.default_internal = Encoding::UTF_8 |
7 | 7 | ||
8 | class Html_parser | 8 | class Html_parser |
9 | - def get_html(lattes_link = "") | 9 | + def get_html(lattes_link = "") |
10 | begin | 10 | begin |
11 | - page = Nokogiri::HTML(open(lattes_link), nil, "UTF-8") | ||
12 | - page = page.css(".main-content").to_s() | ||
13 | - page = remove_class_tooltip(page) | ||
14 | - page = remove_img(page) | ||
15 | - page = remove_select(page) | ||
16 | - page = remove_footer(page) | ||
17 | - page = remove_further_informations(page) | 11 | + page = Nokogiri::HTML(open(lattes_link), nil, "UTF-8") |
12 | + page = page.css(".main-content").to_s() | ||
13 | + page = remove_class_tooltip(page) | ||
14 | + page = remove_img(page) | ||
15 | + page = remove_select(page) | ||
16 | + page = remove_footer(page) | ||
17 | + page = remove_further_informations(page) | ||
18 | rescue | 18 | rescue |
19 | - page = "" | ||
20 | - end | 19 | + page = "" |
20 | + end | ||
21 | end | 21 | end |
22 | 22 | ||
23 | - def remove_class_tooltip(string = "") | ||
24 | - while string.include? 'class="tooltip"' do | ||
25 | - string['class="tooltip"'] = 'class="link_not_to_mark"' | ||
26 | - end | ||
27 | - return string | ||
28 | - end | ||
29 | - | ||
30 | - def remove_img(string = "") | ||
31 | - fist_part_to_keep, *rest = string.split('<img') | ||
32 | - second_part = rest.join(" ") | ||
33 | - part_to_throw_away, *after_img = second_part.split('>',2) | ||
34 | - string = fist_part_to_keep + after_img.join(" ") | 23 | + def remove_class_tooltip(page = "") |
24 | + while page.include? 'class="tooltip"' do | ||
25 | + page['class="tooltip"'] = 'class="link_not_to_mark"' | ||
35 | end | 26 | end |
36 | 27 | ||
37 | - def remove_select(string = "") | ||
38 | - while string.include? '<label' do | ||
39 | - first_part_to_keep, *rest = string.split('<label') | ||
40 | - second_part = rest.join(" ") | ||
41 | - part_to_throw_away, *after_img = second_part.split('</select>') | ||
42 | - string = first_part_to_keep + after_img.join(" ") | ||
43 | - end | ||
44 | - return string | ||
45 | - end | 28 | + return page |
29 | + end | ||
46 | 30 | ||
47 | - def remove_footer(string = "") | ||
48 | - first_part_to_keep, *rest = string.split('<div class="rodape-cv">') | ||
49 | - second_part = rest.join(" ") | ||
50 | - part_to_throw_away, *after_img = second_part.split('Imprimir Currículo</a>') | ||
51 | - string = first_part_to_keep + after_img.join(" ") | ||
52 | - end | 31 | + def remove_img(page = "") |
32 | + fist_part_to_keep, *rest = page.split('<img') | ||
33 | + second_part = rest.join(" ") | ||
34 | + part_to_throw_away, *after_img = second_part.split('>',2) | ||
35 | + page = fist_part_to_keep + after_img.join(" ") | ||
36 | + end | ||
53 | 37 | ||
54 | - def remove_further_informations(string = "") | ||
55 | - first_part_to_keep, *rest = string.split('<a name="OutrasI') | ||
56 | - second_part = rest.join(" ") | ||
57 | - part_to_throw_away, *after_img = second_part.split('</div>',2) | ||
58 | - string = first_part_to_keep + after_img.join(" ") | 38 | + def remove_select(page = "") |
39 | + while page.include? '<label' do | ||
40 | + first_part_to_keep, *rest = page.split('<label') | ||
41 | + second_part = rest.join(" ") | ||
42 | + part_to_throw_away, *after_img = second_part.split('</select>') | ||
43 | + page = first_part_to_keep + after_img.join(" ") | ||
59 | end | 44 | end |
45 | + | ||
46 | + return page | ||
47 | + end | ||
48 | + | ||
49 | + def remove_footer(page = "") | ||
50 | + first_part_to_keep, *rest = page.split('<div class="rodape-cv">') | ||
51 | + second_part = rest.join(" ") | ||
52 | + part_to_throw_away, *after_img = second_part.split('Imprimir Currículo</a>') | ||
53 | + page = first_part_to_keep + after_img.join(" ") | ||
54 | + end | ||
55 | + | ||
56 | + def remove_further_informations(page = "") | ||
57 | + first_part_to_keep, *rest = page.split('<a name="OutrasI') | ||
58 | + second_part = rest.join(" ") | ||
59 | + part_to_throw_away, *after_img = second_part.split('</div>',2) | ||
60 | + page = first_part_to_keep + after_img.join(" ") | ||
61 | + end | ||
60 | end | 62 | end |
plugins/lattes_curriculum/lib/lattes_curriculum_plugin.rb
@@ -16,34 +16,65 @@ class LattesCurriculumPlugin < Noosfero::Plugin | @@ -16,34 +16,65 @@ class LattesCurriculumPlugin < Noosfero::Plugin | ||
16 | true | 16 | true |
17 | end | 17 | end |
18 | 18 | ||
19 | - def signup_extra_contents | ||
20 | - lambda { | ||
21 | - content_tag(:div, labelled_form_field(_('URL Lattes'), text_field(:profile_data, :lattes_url, :id => 'lattes_id_field')) + | ||
22 | - content_tag(:small, _('The Lattes url is the link for your own curriculum so it\'ll be shown on your profile.'), | ||
23 | - :class => 'signup-form', :id => 'lattes-id-balloon'), :id => 'signup-lattes-id') | 19 | + def extra_optional_fields |
20 | + if context.profile && context.profile.person? && context.profile.academic_info.nil? | ||
21 | + context.profile.academic_info = AcademicInfo.new | ||
22 | + end | ||
23 | + | ||
24 | + fields = [] | ||
25 | + | ||
26 | + lattes_url = { | ||
27 | + :name => 'lattes_url', | ||
28 | + :label => 'Lattes URL', | ||
29 | + :object_name => :academic_infos, | ||
30 | + :method => :lattes_url, | ||
31 | + :value => context.profile.nil? ? "" : context.profile.academic_info.lattes_url | ||
24 | } | 32 | } |
33 | + | ||
34 | + fields << lattes_url | ||
35 | + | ||
36 | + return fields | ||
25 | end | 37 | end |
26 | 38 | ||
27 | - def profile_info_extra_contents | ||
28 | - if context.profile.person? | ||
29 | - lattes_url = context.profile.lattes_url | ||
30 | - lambda { | ||
31 | - content_tag('div', labelled_form_field(_('URL Lattes'), text_field_tag('profile_data[lattes_url]', lattes_url, :id => 'lattes_url_field', :disabled => false)) + | ||
32 | - content_tag(:small, _('The url lattes is the link for your lattes curriculum.'))) | ||
33 | - } | ||
34 | - end | 39 | + def extra_person_fields |
40 | + fields = [] | ||
41 | + | ||
42 | + fields << "lattes_url" | ||
43 | + | ||
44 | + return fields | ||
45 | + end | ||
46 | + | ||
47 | + def extra_person_data_params | ||
48 | + {"academic_info_attributes" => context.params[:academic_infos]} | ||
35 | end | 49 | end |
36 | 50 | ||
37 | def profile_tabs | 51 | def profile_tabs |
38 | - unless context.profile.lattes_url.nil? | ||
39 | - href = context.profile.lattes_url | 52 | + unless context.profile.academic_info.nil? || context.profile.academic_info.lattes_url.nil? |
53 | + href = context.profile.academic_info.lattes_url | ||
40 | html_parser = Html_parser.new | 54 | html_parser = Html_parser.new |
41 | - { | ||
42 | - :title => _("Lattes"), | ||
43 | - :id => 'lattes_tab', | ||
44 | - :content => lambda{html_parser.get_html(href)}, | ||
45 | - :start => false | 55 | + { |
56 | + :title => _("Lattes"), | ||
57 | + :id => 'lattes_tab', | ||
58 | + :content => lambda{html_parser.get_html(href)}, | ||
59 | + :start => false | ||
46 | } | 60 | } |
47 | end | 61 | end |
48 | end | 62 | end |
63 | + | ||
64 | + def profile_editor_transaction_extras | ||
65 | + if context.profile.person? | ||
66 | + if context.params.has_key?(:academic_infos) | ||
67 | + academic_info_transaction | ||
68 | + end | ||
69 | + end | ||
70 | + end | ||
71 | + | ||
72 | + protected | ||
73 | + | ||
74 | + def academic_info_transaction | ||
75 | + AcademicInfo.transaction do | ||
76 | + context.profile.academic_info.update_attributes!(context.params[:academic_infos]) | ||
77 | + end | ||
78 | + end | ||
79 | + | ||
49 | end | 80 | end |
plugins/lattes_curriculum/public/singup_complement.js
1 | -jQuery(function($) { | 1 | +jQuery(function($){ |
2 | $(document).ready(function(){ | 2 | $(document).ready(function(){ |
3 | - $('#lattes_id_field').blur(function() { | 3 | + $('#lattes_id_field').blur(function(){ |
4 | var value = this.value | 4 | var value = this.value |
5 | - | ||
6 | }) | 5 | }) |
7 | 6 | ||
8 | - $('#lattes_id_field').focus(function() { | 7 | + $('#lattes_id_field').focus(function(){ |
9 | $('#lattes-id-balloon').fadeIn('slow') | 8 | $('#lattes-id-balloon').fadeIn('slow') |
10 | }) | 9 | }) |
11 | 10 | ||
12 | - $('#lattes_id_field').blur(function() { | 11 | + $('#lattes_id_field').blur(function(){ |
13 | $('#lattes-id-balloon').fadeOut('slow') | 12 | $('#lattes-id-balloon').fadeOut('slow') |
14 | }) | 13 | }) |
15 | }) | 14 | }) |
plugins/lattes_curriculum/test/unit/html_parser_test.rb
@@ -5,7 +5,7 @@ class HtmlParserTest < ActiveSupport::TestCase | @@ -5,7 +5,7 @@ class HtmlParserTest < ActiveSupport::TestCase | ||
5 | def setup | 5 | def setup |
6 | @parser = Html_parser.new | 6 | @parser = Html_parser.new |
7 | end | 7 | end |
8 | - | 8 | + |
9 | should 'be not nil the instance' do | 9 | should 'be not nil the instance' do |
10 | assert_not_nil @parser | 10 | assert_not_nil @parser |
11 | end | 11 | end |
plugins/lattes_curriculum/test/unit/lattes_curriculum_test.rb
@@ -5,7 +5,7 @@ class LattesCurriculumPluginTest < ActiveSupport::TestCase | @@ -5,7 +5,7 @@ class LattesCurriculumPluginTest < ActiveSupport::TestCase | ||
5 | def setup | 5 | def setup |
6 | @plugin = LattesCurriculumPlugin.new | 6 | @plugin = LattesCurriculumPlugin.new |
7 | end | 7 | end |
8 | - | 8 | + |
9 | should 'be a noosfero plugin' do | 9 | should 'be a noosfero plugin' do |
10 | assert_kind_of Noosfero::Plugin, @plugin | 10 | assert_kind_of Noosfero::Plugin, @plugin |
11 | end | 11 | end |