Commit fd23e87459ed5131a3270fcaaa0a4bc0ead1d8d2

Authored by Arthur Esposte
Committed by Daniela Feitosa
1 parent ba117529

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
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 &lt; 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 &lt; 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 &lt; 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 &lt; 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
... ... @@ -1,9 +0,0 @@
1   -class AddUrlLattesToPerson < ActiveRecord::Migration
2   - def self.up
3   - add_column :profiles, :lattes_url, :string
4   - end
5   -
6   - def self.down
7   - remove_column :profiles, :lattes_url
8   - end
9   -end
plugins/lattes_curriculum/db/migrate/20140814210103_create_academic_infos.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class CreateAcademicInfos < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :academic_infos do |t|
  4 + t.references :person
  5 + t.column :lattes_url, :string
  6 + end
  7 + end
  8 +
  9 + def self.down
  10 + drop_table :academic_infos
  11 + end
  12 +end
... ...
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
... ...
plugins/lattes_curriculum/lib/academic_info.rb 0 → 100644
... ... @@ -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 &#39;person&#39;
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&iacute;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&iacute;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 &lt; 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
... ... @@ -5,7 +5,7 @@ class HtmlParserTest &lt; ActiveSupport::TestCase
5 5 def setup
6 6 @parser = Html_parser.new
7 7 end
8   -
  8 +
9 9 should 'be not nil the instance' do
10 10 assert_not_nil @parser
11 11 end
... ...
plugins/lattes_curriculum/test/unit/lattes_curriculum_test.rb
... ... @@ -5,7 +5,7 @@ class LattesCurriculumPluginTest &lt; ActiveSupport::TestCase
5 5 def setup
6 6 @plugin = LattesCurriculumPlugin.new
7 7 end
8   -
  8 +
9 9 should 'be a noosfero plugin' do
10 10 assert_kind_of Noosfero::Plugin, @plugin
11 11 end
... ...