Commit 6d202d97cd19a31eca2810f4e65fafa585fc605d

Authored by Evandro Jr
2 parents 17d350cb 02f12672

Merge branch 'stable' of gitlab.com:participa/noosfero into stable

plugins/virtuoso/controllers/virtuoso_plugin_admin_controller.rb
... ... @@ -47,15 +47,16 @@ class VirtuosoPluginAdminController < AdminController
47 47 to_triple.object = params[:to_triple][:object]
48 48  
49 49 triples_management = VirtuosoPlugin::TriplesManagement.new(environment)
50   - triples_management.update_triple(from_triple, to_triple)
51 50  
52   - render json: { :ok => true, :message => _('Triple succesfully updated.') }
  51 + triple_updated = triples_management.update_triple(from_triple, to_triple)
  52 + message = triple_updated ? _('Triple succesfully updated.') : _('Triple not updated.')
  53 +
  54 + render json: { :ok => triple_updated, :message => message }
53 55 end
54 56 end
55 57  
56 58 def add_triple
57 59 if request.post?
58   -
59 60 triple = VirtuosoPlugin::Triple.new
60 61 triple.graph = params[:triple][:graph]
61 62 triple.subject = params[:triple][:subject]
... ... @@ -63,9 +64,11 @@ class VirtuosoPluginAdminController < AdminController
63 64 triple.object = params[:triple][:object]
64 65  
65 66 triples_management = VirtuosoPlugin::TriplesManagement.new(environment)
66   - triples_management.add_triple(triple)
67 67  
68   - render json: { :ok => true, :message => _('Triple succesfully added.') }
  68 + triple_added = triples_management.add_triple(triple)
  69 + message = triple_added ? _('Triple succesfully added.') : _('Triple not added.')
  70 +
  71 + render json: { :ok => triple_added, :message => message }
69 72 end
70 73 end
71 74  
... ... @@ -78,9 +81,11 @@ class VirtuosoPluginAdminController < AdminController
78 81 triple.object = params[:triple][:object]
79 82  
80 83 triples_management = VirtuosoPlugin::TriplesManagement.new(environment)
81   - triples_management.remove_triple(triple)
82 84  
83   - render json: { :ok => true, :message => _('Triple succesfully removed.') }
  85 + triple_deleted = triples_management.remove_triple(triple)
  86 + message = triple_deleted ? _('Triple succesfully removed.') : _('Triple not removed.')
  87 +
  88 + render json: { :ok => triple_deleted, :message => message }
84 89 end
85 90 end
86 91  
... ...
plugins/virtuoso/lib/virtuoso_plugin/noosfero_harvest.rb 0 → 100644
... ... @@ -0,0 +1,143 @@
  1 +class VirtuosoPlugin::NoosferoHarvest
  2 +
  3 + COMMON_MAPPING = {
  4 + :type => {:predicate => "http://purl.org/dc/terms/type", :value => lambda {|s, t| t.class.name}},
  5 + :created_at => {:predicate => "http://purl.org/dc/terms/created"},
  6 + :updated_at => {:predicate => "http://purl.org/dc/terms/modified"},
  7 + }
  8 +
  9 + ARTICLE_MAPPING = {
  10 + :title => {:predicate => "http://purl.org/dc/terms/title"},
  11 + :abstract => {:predicate => "http://purl.org/dc/terms/abstract"},
  12 + :body => {:predicate => "http://purl.org/dc/terms/description"},
  13 + :part_of => {:predicate => "http://purl.org/dc/terms/isPartOf", :value => lambda {|s, t| url_for(s.url)} },
  14 + :published_at => {:predicate => "http://purl.org/dc/terms/issued"},
  15 + :author => {:predicate => "http://purl.org/dc/terms/creator", :value => lambda {|s, t| url_for(t.author_url) if t.author_url} },
  16 + }
  17 + PROFILE_MAPPING = {
  18 + :name => {:predicate => "http://purl.org/dc/terms/title"},
  19 + :public? => {:predicate => "http://purl.org/socialparticipation/opa#publicProfile"},
  20 + }
  21 + COMMENT_MAPPING = {
  22 + :title => {:predicate => "http://purl.org/dc/terms/title"},
  23 + :body => {:predicate => "http://purl.org/dc/terms/description"},
  24 + :part_of => {:predicate => "http://purl.org/dc/terms/isPartOf", :value => lambda {|s, t| url_for(s.url)} },
  25 + :author => {:predicate => "http://purl.org/dc/terms/creator", :value => lambda {|s, t| url_for(t.author_url) if t.author_url} },
  26 + }
  27 + FRIENDSHIP_MAPPING = {
  28 + :knows => {:predicate => "http://xmlns.com/foaf/0.1/knows", :value => lambda {|s, t| url_for(t.url)} },
  29 + :type => nil, :created_at => nil, :updated_at => nil,
  30 + }
  31 +
  32 + def initialize(environment)
  33 + @environment = environment
  34 + @graph = environment.top_url
  35 + end
  36 +
  37 + attr_reader :environment
  38 +
  39 + def plugin
  40 + @plugin ||= VirtuosoPlugin.new(self)
  41 + end
  42 +
  43 + delegate :settings, :to => :plugin
  44 +
  45 + include Rails.application.routes.url_helpers
  46 + include ActionView::Helpers::SanitizeHelper
  47 +
  48 + def triplify_comments(article)
  49 + total = article.comments.count
  50 + count = 0
  51 + article.comments.find_each do |comment|
  52 + begin
  53 + subject_identifier = url_for(comment.url)
  54 + puts "triplify #{subject_identifier} comment (#{count+=1}/#{total})"
  55 + triplify_mappings(COMMENT_MAPPING, subject_identifier, article, comment)
  56 + rescue => ex
  57 + puts "FAILED: #{ex}"
  58 + end
  59 + end
  60 + end
  61 +
  62 + def triplify_articles(profile)
  63 + total = profile.articles.count
  64 + count = 0
  65 + profile.articles.public.each do |article|
  66 + begin
  67 + subject_identifier = url_for(article.url)
  68 + puts "triplify #{subject_identifier} article (#{count+=1}/#{total})"
  69 + triplify_mappings(ARTICLE_MAPPING, subject_identifier, profile, article)
  70 + triplify_comments(article)
  71 + rescue => ex
  72 + puts "FAILED: #{ex}"
  73 + end
  74 + end
  75 + end
  76 +
  77 + def triplify_friendship(person)
  78 + total = person.friends.count
  79 + count = 0
  80 + person.friends.each do |friend|
  81 + begin
  82 + subject_identifier = url_for(person.url)
  83 + puts "triplify #{subject_identifier} friendship (#{count+=1}/#{total})"
  84 + triplify_mappings(FRIENDSHIP_MAPPING, subject_identifier, person, friend)
  85 + rescue => ex
  86 + puts "FAILED: #{ex}"
  87 + end
  88 + end
  89 + end
  90 +
  91 + def triplify_profiles
  92 + total = environment.profiles.count
  93 + count = 0
  94 + environment.profiles.find_each do |profile|
  95 + begin
  96 + subject_identifier = url_for(profile.url)
  97 + puts "triplify #{subject_identifier} profile (#{count+=1}/#{total})"
  98 + triplify_mappings(PROFILE_MAPPING, subject_identifier, environment, profile)
  99 + triplify_articles(profile) if profile.public?
  100 + triplify_friendship(profile) if profile.person?
  101 + rescue => ex
  102 + puts "FAILED: #{ex}"
  103 + end
  104 + end
  105 + end
  106 +
  107 + def run
  108 + triplify_profiles
  109 + end
  110 +
  111 + protected
  112 +
  113 + def triplify_mappings(mapping, subject_identifier, source, target)
  114 + COMMON_MAPPING.merge(mapping).each do |k, v|
  115 + next unless v
  116 + value = nil
  117 + if v[:value]
  118 + value = v[:value].kind_of?(Proc) ? v[:value].call(source, target) : v[:value]
  119 + elsif target.respond_to?(k)
  120 + value = target.send(k)
  121 + end
  122 + insert_triple(RDF::URI.new(subject_identifier), RDF::URI.new(v[:predicate]), value) if value.present?
  123 + end
  124 + end
  125 +
  126 + def process_value(value)
  127 + if value.kind_of?(String)
  128 + value = /https?:\/\//.match(value) ? RDF::URI.new(value) : strip_tags(value)
  129 + elsif value.kind_of?(ActiveSupport::TimeWithZone)
  130 + value = RDF::Literal::DateTime.new(value)
  131 + elsif !!value == value
  132 + value = RDF::Literal::Boolean.new(value)
  133 + end
  134 + end
  135 +
  136 + def insert_triple(subject, predicate, value)
  137 + query = RDF::Virtuoso::Query.insert_data([RDF::URI.new(subject),
  138 + RDF::URI.new(predicate),
  139 + process_value(value)]).graph(RDF::URI.new(@graph))
  140 + plugin.virtuoso_client.insert(query)
  141 + end
  142 +
  143 +end
... ...
plugins/virtuoso/lib/virtuoso_plugin/triples_management.rb
... ... @@ -18,17 +18,37 @@ class VirtuosoPlugin::TriplesManagement
18 18 def update_triple(from_triple, to_triple)
19 19 query = "WITH <#{from_triple.graph}> DELETE { <#{from_triple.subject}> <#{from_triple.predicate}> #{from_triple.object} } INSERT { <#{to_triple.subject}> <#{to_triple.predicate}> #{to_triple.object} }"
20 20  
21   - plugin.virtuoso_client.query(query)
  21 + begin
  22 + query_result = plugin.virtuoso_client.query(query)[0][:"callret-0"].to_s
  23 + rescue RDF::Virtuoso::Repository::MalformedQuery => e
  24 + query_result = e.to_s
  25 + end
  26 +
  27 + return query_result =~ /^Modify.*done$/ ? true : false
22 28 end
23 29  
24 30 def add_triple(triple)
25 31 query = "WITH <#{triple.graph}> INSERT { <#{triple.subject}> <#{triple.predicate}> #{triple.object} }"
26   - plugin.virtuoso_client.query(query)
  32 +
  33 + begin
  34 + query_result = plugin.virtuoso_client.query(query)[0][:"callret-0"].to_s
  35 + rescue RDF::Virtuoso::Repository::MalformedQuery => e
  36 + query_result = e.to_s
  37 + end
  38 +
  39 + return query_result =~ /^Insert.*done$/ ? true : false
27 40 end
28 41  
29 42 def remove_triple(triple)
30 43 query = "WITH <#{triple.graph}> DELETE { <#{triple.subject}> <#{triple.predicate}> #{triple.object} }"
31   - plugin.virtuoso_client.query(query)
  44 +
  45 + begin
  46 + query_result = plugin.virtuoso_client.query(query)[0][:"callret-0"].to_s
  47 + rescue RDF::Virtuoso::Repository::MalformedQuery => e
  48 + query_result = e.to_s
  49 + end
  50 +
  51 + return query_result =~ /^Delete.*done$/ ? true : false
32 52 end
33 53  
34 54 end
... ...
plugins/virtuoso/public/triples_management.js
  1 +function is_valid_url(url) {
  2 + var pattern =/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/i;
  3 + return pattern.test(url);
  4 +}
  5 +
  6 +function validate_search_form() {
  7 + graph_uri = jQuery("input#graph_uri");
  8 + query = jQuery("textarea#query");
  9 +
  10 + if ( !is_valid_url(graph_uri.val())) {
  11 + alert( TRIPLES_MANAGEMENT_GRAPH_URI_REQUIRED_MESSAGE );
  12 + graph_uri.focus();
  13 + return false;
  14 + }
  15 +
  16 + pattern = /.*select\s.*/i
  17 + if (!pattern.test(query.val())) {
  18 + alert( TRIPLES_MANAGEMENT_QUERY_REQUIRED_MESSAGE );
  19 + query.focus();
  20 + return false;
  21 + }
  22 +
  23 + jQuery("#form-triples-search").submit();
  24 +
  25 +}
  26 +
1 27 function update_triple(triple_id) {
2 28 graph = jQuery("input#graph_uri").val();
3 29  
... ... @@ -20,17 +46,14 @@ function update_triple(triple_id) {
20 46 url: '/admin/plugin/virtuoso/update_triple',
21 47 data: formData,
22 48 dataType: 'json',
23   - success: function(data, status, ajax){
  49 + success: function(data, status, ajax) {
24 50 if ( !data.ok ) {
25   - display_notice(data.error.message);
  51 + display_notice(data.message);
26 52 }
27 53 else {
28 54 display_notice(data.message);
29 55 jQuery("input#triples_triple" + triple_id + "_from_object").val(jQuery("input#triples_triple" + triple_id + "_to_object").val());
30 56 }
31   - },
32   - error: function(ajax, status, errorThrown) {
33   - alert('Send request - HTTP '+status+': '+errorThrown);
34 57 }
35 58 });
36 59  
... ... @@ -50,18 +73,9 @@ function add_triple() {
50 73 url: '/admin/plugin/virtuoso/add_triple',
51 74 data: formData,
52 75 dataType: 'json',
53   - success: function(data, status, ajax){
54   - if ( !data.ok ) {
55   - display_notice(data.error.message);
56   - jQuery.colorbox.close();
57   - }
58   - else {
59   - display_notice(data.message);
60   - jQuery.colorbox.close();
61   - }
62   - },
63   - error: function(ajax, status, errorThrown) {
64   - alert('Send request - HTTP '+status+': '+errorThrown);
  76 + success: function(data, status, ajax) {
  77 + display_notice(data.message);
  78 + jQuery.colorbox.close();
65 79 }
66 80 });
67 81  
... ... @@ -84,7 +98,7 @@ function remove_triple(triple_id) {
84 98 dataType: 'json',
85 99 success: function(data, status, ajax){
86 100 if ( !data.ok ) {
87   - display_notice(data.error.message);
  101 + display_notice(data.message);
88 102 }
89 103 else {
90 104 display_notice(data.message);
... ... @@ -97,9 +111,6 @@ function remove_triple(triple_id) {
97 111 }
98 112 });
99 113 }
100   - },
101   - error: function(ajax, status, errorThrown) {
102   - alert('Send request - HTTP '+status+': '+errorThrown);
103 114 }
104 115 });
105 116  
... ...
plugins/virtuoso/test/functional/virtuoso_plugin_admin_controller_test.rb
... ... @@ -8,7 +8,6 @@ class VirtuosoPluginAdminControllerTest &lt; ActionController::TestCase
8 8 @environment = Environment.default
9 9 @profile = create_user('profile').person
10 10 login_as(@profile.identifier)
11   - post :index, :settings => mock_settings
12 11 end
13 12  
14 13 def mock_settings
... ... @@ -26,6 +25,7 @@ class VirtuosoPluginAdminControllerTest &lt; ActionController::TestCase
26 25 end
27 26  
28 27 should 'save virtuoso plugin settings' do
  28 + post :index, :settings => mock_settings
29 29 @settings = Noosfero::Plugin::Settings.new(environment.reload, VirtuosoPlugin)
30 30 assert_equal 'http://virtuoso.noosfero.com', @settings.settings[:virtuoso_uri]
31 31 assert_equal 'username', @settings.settings[:virtuoso_username]
... ... @@ -38,28 +38,33 @@ class VirtuosoPluginAdminControllerTest &lt; ActionController::TestCase
38 38 assert_redirected_to :action => 'index'
39 39 end
40 40  
41   -
42 41 should 'redirect to index after save' do
43 42 post :index, :settings => mock_settings
44 43 assert_redirected_to :action => 'index'
45 44 end
46 45  
47 46 should 'create delayed job to start harvest on force action' do
48   - harvest = VirtuosoPlugin::DspaceHarvest.new(environment)
  47 + post :index, :settings => mock_settings
  48 + harvest = VirtuosoPlugin::DspaceHarvest.new(environment, "http://dspace1.noosfero.com")
49 49 assert !harvest.find_job.present?
50 50 get :force_harvest
51 51 assert harvest.find_job.present?
52 52 end
53 53  
54 54 should 'force harvest from start' do
  55 + post :index, :settings => mock_settings
55 56 get :force_harvest, :from_start => true
56   - harvest = VirtuosoPlugin::DspaceHarvest.new(environment)
  57 + harvest = VirtuosoPlugin::DspaceHarvest.new(environment, "http://dspace2.noosfero.com")
57 58 assert harvest.find_job.present?
58 59 assert_equal nil, harvest.settings.last_harvest
59 60 end
60   -
61   - should 'force harvest_all from start' do
62   - get :force_harvest, :from_start => true
  61 +
  62 + should 'not create delayed job to start harvest on force action without settings' do
  63 + post :index, :settings => mock_settings
  64 + harvest = VirtuosoPlugin::DspaceHarvest.new(environment, "http://dspace8.noosfero.com")
  65 + assert !harvest.find_job.present?, "testing if no job is running"
  66 + get :force_harvest
  67 + assert !harvest.find_job.present?, "testing if no job is running again"
63 68 end
64   -
65   -end
66 69 \ No newline at end of file
  70 +
  71 +end
... ...
plugins/virtuoso/test/unit/dspace_harvest_test.rb
... ... @@ -23,6 +23,8 @@ class DspaceHarvestTest &lt; ActiveSupport::TestCase
23 23 end
24 24  
25 25 should 'create delayed job when start' do
  26 + @settings = Noosfero::Plugin::Settings.new(environment, VirtuosoPlugin, mock_settings)
  27 + @settings.save!
26 28 harvest = VirtuosoPlugin::DspaceHarvest.new(environment, "http://dspace1.noosfero.com")
27 29 assert !harvest.find_job.present?
28 30 harvest.start
... ... @@ -30,16 +32,14 @@ class DspaceHarvestTest &lt; ActiveSupport::TestCase
30 32 end
31 33  
32 34 should 'not duplicate harvest job' do
  35 + @settings = Noosfero::Plugin::Settings.new(environment, VirtuosoPlugin, mock_settings)
  36 + @settings.save!
33 37 harvest = VirtuosoPlugin::DspaceHarvest.new(environment, "http://dspace1.noosfero.com")
34 38 assert_difference "harvest.find_job.count", 1 do
35 39 5.times { harvest.start }
36 40 end
37 41 end
38 42  
39   - should 'harvest all dspaces from start' do
40   - VirtuosoPlugin::DspaceHarvest.harvest_all(environment, true)
41   - end
42   -
43 43 should 'try to harvest all dspaces from start without any setting' do
44 44 VirtuosoPlugin::DspaceHarvest.harvest_all(environment, true)
45 45 end
... ...
plugins/virtuoso/views/virtuoso_plugin_admin/triple_management.html.erb
1 1 <div id="virtuoso-triples-management">
2 2 <h1><%= _('Virtuoso settings &raquo; Triples Management')%></h1>
3 3  
4   - <%= form_tag('/admin/plugin/virtuoso/triples_management', :method => 'post') do %>
  4 + <%= form_tag('/admin/plugin/virtuoso/triples_management', :method => 'post', :id => 'form-triples-search') do %>
5 5 <%= labelled_form_field(_('Graph URI:'), text_field_tag(:graph_uri, @graph_uri) ) %>
6 6 <%= labelled_form_field(_('Query SPARQL:'), text_area_tag(:query, @query, :rows => 7)) %>
7 7 <% button_bar do %>
8   - <%= submit_button(:search, _('Search triples')) %>
  8 + <%= submit_button(:search, _('Search triples'), :onclick => "validate_search_form(); return false;") %>
9 9 <%= colorbox_button('add', _('Add a triple'), { :action => 'add_triple' }) %>
10 10 <% end %>
11 11 <% end %>
... ... @@ -54,4 +54,9 @@
54 54  
55 55 </div>
56 56  
  57 +<script type="text/javascript">
  58 + TRIPLES_MANAGEMENT_GRAPH_URI_REQUIRED_MESSAGE = '<%= _('A valid GRAPH URI is required') %>';
  59 + TRIPLES_MANAGEMENT_QUERY_REQUIRED_MESSAGE = '<%= _('A valid QUERY is required') %>';
  60 +</script>
  61 +
57 62 <%= javascript_include_tag '/plugins/virtuoso/triples_management.js' %>
... ...