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 | 17 | |
| 18 | 18 | def manage_fields |
| 19 | 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 | 24 | @enterprise_fields = Enterprise.fields |
| 21 | 25 | @community_fields = Community.fields |
| 22 | 26 | end | ... | ... |
app/controllers/my_profile/profile_editor_controller.rb
| ... | ... | @@ -15,14 +15,22 @@ class ProfileEditorController < MyProfileController |
| 15 | 15 | @possible_domains = profile.possible_domains |
| 16 | 16 | if request.post? |
| 17 | 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 | 33 | end |
| 25 | - end | |
| 26 | 34 | end |
| 27 | 35 | end |
| 28 | 36 | end | ... | ... |
app/controllers/public/account_controller.rb
| ... | ... | @@ -93,7 +93,13 @@ class AccountController < ApplicationController |
| 93 | 93 | @user.terms_of_use = environment.terms_of_use |
| 94 | 94 | @user.environment = environment |
| 95 | 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 | 103 | @user.return_to = session[:return_to] |
| 98 | 104 | @person = Person.new(params[:profile_data]) |
| 99 | 105 | @person.environment = @user.environment | ... | ... |
app/models/user.rb
| ... | ... | @@ -29,6 +29,8 @@ class User < ActiveRecord::Base |
| 29 | 29 | alias_method_chain :human_attribute_name, :customization |
| 30 | 30 | end |
| 31 | 31 | |
| 32 | + include Noosfero::Plugin::HotSpot | |
| 33 | + | |
| 32 | 34 | before_create do |user| |
| 33 | 35 | if user.environment.nil? |
| 34 | 36 | user.environment = Environment.default |
| ... | ... | @@ -46,6 +48,7 @@ class User < ActiveRecord::Base |
| 46 | 48 | p.environment = user.environment |
| 47 | 49 | p.name ||= user.name || user.login |
| 48 | 50 | p.visible = false unless user.activated? |
| 51 | + | |
| 49 | 52 | p.save! |
| 50 | 53 | |
| 51 | 54 | user.person = p | ... | ... |
app/views/profile_editor/_person_form.html.erb
| ... | ... | @@ -27,6 +27,10 @@ |
| 27 | 27 | <%= optional_field(@person, 'district', labelled_form_field(_('District'), text_field(:profile_data, :district, :rel => _('District')))) %> |
| 28 | 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 | 34 | <% optional_field(@person, 'schooling') do %> |
| 31 | 35 | <div class="formfieldline"> |
| 32 | 36 | <label class='formlabel' for='profile_data_schooling'><%= _('Schooling') %></label> | ... | ... |
lib/noosfero/plugin.rb
| ... | ... | @@ -531,6 +531,29 @@ class Noosfero::Plugin |
| 531 | 531 | nil |
| 532 | 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 | 557 | # -> Adds additional blocks to profiles and environments. |
| 535 | 558 | # Your plugin must implements a class method called 'extra_blocks' |
| 536 | 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 @@ |
| 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 | 25 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -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 | 2 | |
| 3 | 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 | 13 | end |
| 14 | 14 | |
| 15 | -end | |
| 16 | 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 | 6 | Encoding.default_internal = Encoding::UTF_8 |
| 7 | 7 | |
| 8 | 8 | class Html_parser |
| 9 | - def get_html(lattes_link = "") | |
| 9 | + def get_html(lattes_link = "") | |
| 10 | 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 | 18 | rescue |
| 19 | - page = "" | |
| 20 | - end | |
| 19 | + page = "" | |
| 20 | + end | |
| 21 | 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 | 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 | 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 | 62 | end | ... | ... |
plugins/lattes_curriculum/lib/lattes_curriculum_plugin.rb
| ... | ... | @@ -16,34 +16,65 @@ class LattesCurriculumPlugin < Noosfero::Plugin |
| 16 | 16 | true |
| 17 | 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 | 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 | 49 | end |
| 36 | 50 | |
| 37 | 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 | 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 | 61 | end |
| 48 | 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 | 80 | end | ... | ... |
plugins/lattes_curriculum/public/singup_complement.js
| 1 | -jQuery(function($) { | |
| 1 | +jQuery(function($){ | |
| 2 | 2 | $(document).ready(function(){ |
| 3 | - $('#lattes_id_field').blur(function() { | |
| 3 | + $('#lattes_id_field').blur(function(){ | |
| 4 | 4 | var value = this.value |
| 5 | - | |
| 6 | 5 | }) |
| 7 | 6 | |
| 8 | - $('#lattes_id_field').focus(function() { | |
| 7 | + $('#lattes_id_field').focus(function(){ | |
| 9 | 8 | $('#lattes-id-balloon').fadeIn('slow') |
| 10 | 9 | }) |
| 11 | 10 | |
| 12 | - $('#lattes_id_field').blur(function() { | |
| 11 | + $('#lattes_id_field').blur(function(){ | |
| 13 | 12 | $('#lattes-id-balloon').fadeOut('slow') |
| 14 | 13 | }) |
| 15 | 14 | }) | ... | ... |
plugins/lattes_curriculum/test/unit/html_parser_test.rb
plugins/lattes_curriculum/test/unit/lattes_curriculum_test.rb