Commit fa512fa6f81c2e90cb20a450efb682f05bb73d7b
1 parent
9c61af94
Exists in
staging
and in
4 other branches
virtuoso: added a plugin for integration with virtuoso
Showing
9 changed files
with
226 additions
and
0 deletions
Show diff stats
plugins/virtuoso/controllers/virtuoso_plugin_admin_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,23 @@ |
1 | +class VirtuosoPluginAdminController < AdminController | |
2 | + | |
3 | + def index | |
4 | + settings = params[:settings] | |
5 | + settings ||= {} | |
6 | + @settings = Noosfero::Plugin::Settings.new(environment, VirtuosoPlugin, settings) | |
7 | + @harvest_running = VirtuosoPlugin::DspaceHarvest.new(environment).find_job.present? | |
8 | + | |
9 | + if request.post? | |
10 | + @settings.save! | |
11 | + session[:notice] = 'Settings succefully saved.' | |
12 | + redirect_to :action => 'index' | |
13 | + end | |
14 | + end | |
15 | + | |
16 | + def force_harvest | |
17 | + harvest = VirtuosoPlugin::DspaceHarvest.new(environment) | |
18 | + harvest.start | |
19 | + session[:notice] = _('Harvest started') | |
20 | + redirect_to :action => :index | |
21 | + end | |
22 | + | |
23 | +end | ... | ... |
... | ... | @@ -0,0 +1,71 @@ |
1 | +#inspired by https://github.com/code4lib/ruby-oai/blob/master/lib/oai/harvester/harvest.rb | |
2 | +class VirtuosoPlugin::DspaceHarvest | |
3 | + | |
4 | + DC_CONVERSION = [:title, :creator, :subject, :description, :date, :type, :identifier, :language, :rights, :format] | |
5 | + | |
6 | + def initialize(environment) | |
7 | + @environment = environment | |
8 | + end | |
9 | + | |
10 | + def settings | |
11 | + @settings ||= Noosfero::Plugin::Settings.new(@environment, VirtuosoPlugin) | |
12 | + end | |
13 | + | |
14 | + def dspace_client | |
15 | + @dspace_client ||= OAI::Client.new("#{settings.dspace_uri}/oai/request") | |
16 | + end | |
17 | + | |
18 | + def virtuoso_client | |
19 | + @virtuoso_client ||= RDF::Virtuoso::Repository.new("#{settings.virtuoso_uri}/sparql", :update_uri => "#{settings.virtuoso_uri}/sparql-auth", :username => settings.virtuoso_username, :password => settings.virtuoso_password, :auth_method => 'digest', :timeout => 30) | |
20 | + end | |
21 | + | |
22 | + def triplify(record) | |
23 | + metadata = VirtuosoPlugin::DublinCoreMetadata.new(record.metadata) | |
24 | + puts "triplify #{record.header.identifier}" | |
25 | + | |
26 | + DC_CONVERSION.each do |c| | |
27 | + values = [metadata.send(c)].flatten.compact | |
28 | + values.each do |value| | |
29 | + query = RDF::Virtuoso::Query.insert_data([RDF::URI.new(metadata.identifier), RDF::URI.new("http://purl.org/dc/elements/1.1/#{c}"), value]).graph(RDF::URI.new(settings.dspace_uri)) | |
30 | + virtuoso_client.insert(query) | |
31 | + end | |
32 | + end | |
33 | + end | |
34 | + | |
35 | + def run | |
36 | + harvest_time = Time.now.utc | |
37 | + params = settings.last_harvest ? {:from => settings.last_harvest.utc} : {} | |
38 | + puts "starting harvest #{params}" | |
39 | + begin | |
40 | + records = dspace_client.list_records(params) | |
41 | + records.each do |record| | |
42 | + triplify(record) | |
43 | + end | |
44 | + rescue Exception => ex | |
45 | + puts ex.to_s | |
46 | + end | |
47 | + settings.last_harvest = harvest_time | |
48 | + settings.save! | |
49 | + puts "ending harvest #{harvest_time}" | |
50 | + end | |
51 | + | |
52 | + def start | |
53 | + if find_job.empty? | |
54 | + job = VirtuosoPlugin::DspaceHarvest::Job.new(@environment.id) | |
55 | + Delayed::Job.enqueue(job) | |
56 | + end | |
57 | + end | |
58 | + | |
59 | + def find_job | |
60 | + Delayed::Job.where(:handler => "--- !ruby/struct:VirtuosoPlugin::DspaceHarvest::Job\nenvironment_id: #{@environment.id}\n") | |
61 | + end | |
62 | + | |
63 | + class Job < Struct.new(:environment_id) | |
64 | + def perform | |
65 | + environment = Environment.find(environment_id) | |
66 | + harvest = VirtuosoPlugin::DspaceHarvest.new(environment) | |
67 | + harvest.run | |
68 | + end | |
69 | + end | |
70 | + | |
71 | +end | ... | ... |
plugins/virtuoso/lib/virtuoso_plugin/dublin_core_metadata.rb
0 → 100644
... | ... | @@ -0,0 +1,20 @@ |
1 | +class VirtuosoPlugin::DublinCoreMetadata | |
2 | + | |
3 | + include OAI::XPath | |
4 | + | |
5 | + attr_accessor :date, :title, :creator, :subject, :description, :date, :type, :identifier, :language, :rights, :format | |
6 | + | |
7 | + def initialize(element) | |
8 | + @title = xpath(element, './/dc:title') | |
9 | + @creator = xpath(element, './/dc:creator') | |
10 | + @subject = xpath_all(element, './/dc:subject').map(&:text) | |
11 | + @description = xpath(element, './/dc:description') | |
12 | + @date = xpath_all(element, './/dc:date').map(&:text) | |
13 | + @type = xpath(element, './/dc:type') | |
14 | + @identifier = xpath(element, './/dc:identifier') | |
15 | + @language = xpath(element, './/dc:language') | |
16 | + @rights = xpath_all(element, './/dc:rights').map(&:text) | |
17 | + @format = xpath(element, './/dc:format') | |
18 | + end | |
19 | + | |
20 | +end | ... | ... |
plugins/virtuoso/test/functional/virtuoso_plugin_admin_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,38 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class VirtuosoPluginAdminControllerTest < ActionController::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @environment = Environment.default | |
7 | + @profile = create_user('profile').person | |
8 | + login_as(@profile.identifier) | |
9 | + end | |
10 | + | |
11 | + attr_reader :environment | |
12 | + | |
13 | + should 'save virtuoso plugin settings' do | |
14 | + post :index, :settings => {'virtuoso_uri' => 'http://virtuoso.noosfero.com', | |
15 | + 'virtuoso_username' => 'username', | |
16 | + 'virtuoso_password' => 'password', | |
17 | + 'dspace_uri' => 'http://dspace.noosfero.com'} | |
18 | + @settings = Noosfero::Plugin::Settings.new(environment.reload, VirtuosoPlugin) | |
19 | + assert_equal 'http://virtuoso.noosfero.com', @settings.settings[:virtuoso_uri] | |
20 | + assert_equal 'username', @settings.settings[:virtuoso_username] | |
21 | + assert_equal 'password', @settings.settings[:virtuoso_password] | |
22 | + assert_equal 'http://dspace.noosfero.com', @settings.settings[:dspace_uri] | |
23 | + assert_redirected_to :action => 'index' | |
24 | + end | |
25 | + | |
26 | + should 'redirect to index after save' do | |
27 | + post :index, :settings => {"virtuoso_uri" => 'http://virtuoso.noosfero.com'} | |
28 | + assert_redirected_to :action => 'index' | |
29 | + end | |
30 | + | |
31 | + should 'create delayed job to start harvest on force action' do | |
32 | + harvest = VirtuosoPlugin::DspaceHarvest.new(environment) | |
33 | + assert !harvest.find_job.present? | |
34 | + get :force_harvest | |
35 | + assert harvest.find_job.present? | |
36 | + end | |
37 | + | |
38 | +end | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +require File.dirname(__FILE__) + '/../../../test/test_helper' | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | + | |
3 | +class DspaceHarvestTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @environment = Environment.default | |
7 | + end | |
8 | + | |
9 | + attr_reader :environment | |
10 | + | |
11 | + should 'create delayed job when start' do | |
12 | + harvest = VirtuosoPlugin::DspaceHarvest.new(environment) | |
13 | + assert !harvest.find_job.present? | |
14 | + harvest.start | |
15 | + assert harvest.find_job.present? | |
16 | + end | |
17 | + | |
18 | + should 'not duplicate harvest job' do | |
19 | + harvest = VirtuosoPlugin::DspaceHarvest.new(environment) | |
20 | + assert_difference "harvest.find_job.count", 1 do | |
21 | + 5.times { harvest.start } | |
22 | + end | |
23 | + end | |
24 | + | |
25 | +end | ... | ... |
plugins/virtuoso/views/virtuoso_plugin_admin/index.html.erb
0 → 100644
... | ... | @@ -0,0 +1,34 @@ |
1 | +<h1><%= _('Virtuoso settings')%></h1> | |
2 | + | |
3 | +<%= form_for(:settings) do |f| %> | |
4 | + | |
5 | + <strong> | |
6 | + <%= labelled_form_field _('Virtuoso URL:'), f.text_field(:virtuoso_uri) %> | |
7 | + <%= labelled_form_field _('Virtuoso Username:'), f.text_field(:virtuoso_username) %> | |
8 | + <%= labelled_form_field _('Virtuoso Password:'), f.password_field(:virtuoso_password) %> | |
9 | + <%= labelled_form_field _('DSpace URL:'), f.text_field(:dspace_uri) %> | |
10 | + </strong> | |
11 | + | |
12 | + <% button_bar do %> | |
13 | + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %> | |
14 | + <% end %> | |
15 | + | |
16 | +<% end %> | |
17 | + | |
18 | +<hr/> | |
19 | +<div class="harvest"> | |
20 | + <% if @settings.last_harvest %> | |
21 | + <div class="date"> | |
22 | + <span class="label"><strong><%= _('Last execution:') %></strong></span> | |
23 | + <span class="value"><%= time_ago_as_sentence @settings.last_harvest %></span> | |
24 | + </div> | |
25 | +<% end %> | |
26 | + <br/> | |
27 | + <div class="actions"> | |
28 | + <% if @harvest_running %> | |
29 | + <%= _('Running...') %> | |
30 | + <% else %> | |
31 | + <%= button :next, _('Force harvest'), :action => :force_harvest %> | |
32 | + <% end %> | |
33 | + </div> | |
34 | +</div> | ... | ... |