metacrunch 2.1.0.pre1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3651a2620048f6cf78fd1d1670a1f211c5c39dac
4
- data.tar.gz: acdfb9744c06a0d7f8725434b9fde56588135bad
3
+ metadata.gz: d28e81a93e97edc9aa9016c18587317304ca0d68
4
+ data.tar.gz: 19ec0fccbef5888f0397b6d2abd3c404f7878172
5
5
  SHA512:
6
- metadata.gz: e2ce0cf3aef3e033c60402ca81d9b568c598b2039c75adb4658fa930d2b9b41c5f2c14ca90e9df058bccb32da08f7c9a3e5f7d87c09d92566426cb46854b3868
7
- data.tar.gz: 046c114e1d674aff5d4ce17539da4fac30b58ed3960307fc24f00bbe4f67fbfece6c483830da099eca912423c74485bc8b0aba617d307cdc72fe07fd947d7828
6
+ metadata.gz: 7f5636649b8bb785b58ba4995aac662803a1901a0b24910ea3eaa2847f86c90a7382a45bd3ad99562548246f8ddefe97af017161074bf09e57ed6686a65c6d6b
7
+ data.tar.gz: 121cb6f44102a87e13520f8dfde8e8b2feef04329649fbc7d9ec7f93fff652d07bc42b9a84e8cde71760edaf690ccf3e5d5954439d47ce13bc96c6bf2121cd29
data/.gitignore CHANGED
@@ -1,5 +1,5 @@
1
1
  .DS_Store
2
- pkg
3
- Gemfile.lock
4
- .yardoc
5
- doc
2
+ /Gemfile.lock
3
+ /.yardoc
4
+ /doc
5
+ /*.gem
data/Readme.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # metacrunch
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/metacrunch.svg)](http://badge.fury.io/rb/metacrunch)
3
4
  [![Code Climate](https://codeclimate.com/github/ubpb/metacrunch/badges/gpa.svg)](https://codeclimate.com/github/ubpb/metacrunch)
4
5
  [![Build Status](https://travis-ci.org/ubpb/metacrunch.svg)](https://travis-ci.org/ubpb/metacrunch)
5
6
 
@@ -0,0 +1,29 @@
1
+ module Metacrunch
2
+ class Cli
3
+ class Base < Thor
4
+ no_commands do
5
+ def self.register_thor_command(command_definition)
6
+ desc(command_definition.usage, command_definition.desc)
7
+
8
+ command_definition.options.each do |key, value|
9
+ option(key, value)
10
+ end
11
+
12
+ define_method(command_definition.name) do |*params|
13
+ run_command(command_definition.command_class, params)
14
+ end
15
+ end
16
+
17
+ def run_command(command, params = [])
18
+ klass = command.class == Class ? command : command.to_s.constantize
19
+ raise ArgumentError, "command must be a Metacrunch::Command class" unless klass < Metacrunch::Command
20
+
21
+ command = klass.new(shell, options, params)
22
+ command.pre_perform
23
+ command.perform
24
+ command.post_perform
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ module Metacrunch
2
+ class Cli
3
+ class CommandDefinition
4
+ def initialize(command_class, description)
5
+ @klass = command_class
6
+ @name = nil
7
+ @description = description
8
+ @usage = nil
9
+ @options = {}
10
+ end
11
+
12
+ def command_class(value = nil)
13
+ @klass if value
14
+ @klass
15
+ end
16
+
17
+ def name
18
+ name = @klass.to_s.demodulize.underscore
19
+ name.gsub!(/_command\Z/, "")
20
+ end
21
+
22
+ def usage(value = nil)
23
+ @usage = value if value.present?
24
+ @usage || name
25
+ end
26
+
27
+ def desc(value = nil)
28
+ @description = value if value.present?
29
+ @description
30
+ end
31
+
32
+ def option(name, options = {})
33
+ @options[name] = options
34
+ end
35
+
36
+ def options
37
+ @options
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ module Metacrunch
2
+ class Cli
3
+ class CommandRegistry
4
+ attr_reader :commands
5
+
6
+ def initialize
7
+ @commands = []
8
+ end
9
+
10
+ def register(klass, description = nil, &block)
11
+ command = CommandDefinition.new(klass, description)
12
+ yield(command) if block_given?
13
+ @commands << command
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module Metacrunch
2
+ class Cli
3
+ class Main < Thor
4
+ # Define metacrunch root commands here
5
+ end
6
+ end
7
+ end
@@ -1,4 +1,26 @@
1
1
  module Metacrunch
2
- class Cli < Thor
2
+ class Cli
3
+ require_relative "./cli/main"
4
+ require_relative "./cli/base"
5
+ require_relative "./cli/command_registry"
6
+ require_relative "./cli/command_definition"
7
+
8
+ def self.start(argv)
9
+ Main.start(argv)
10
+ end
11
+
12
+ def self.setup(namespace, description, &block)
13
+ klass = Class.new(Base)
14
+ klass.namespace(namespace)
15
+
16
+ registry = CommandRegistry.new
17
+ yield(registry)
18
+
19
+ registry.commands.each do |c|
20
+ klass.register_thor_command(c)
21
+ end
22
+
23
+ Main.register(klass, namespace, "#{namespace} [COMMAND]", description)
24
+ end
3
25
  end
4
26
  end
@@ -3,11 +3,24 @@ module Metacrunch
3
3
 
4
4
  attr_reader :shell
5
5
  attr_reader :options
6
+ attr_reader :params
6
7
 
7
- def initialize(shell:, options:)
8
+ def initialize(shell, options = {}, params = [])
8
9
  @shell = shell
9
10
  @options = options
10
- setup if self.respond_to?(:setup)
11
+ @params = params
12
+ end
13
+
14
+ def pre_perform
15
+ # can be implemented in sub-class
16
+ end
17
+
18
+ def perform
19
+ raise NotImplementedError, "You must implement .perform() in your command sub-class"
20
+ end
21
+
22
+ def post_perform
23
+ # can be implemented in sub-class
11
24
  end
12
25
 
13
26
  end
@@ -0,0 +1,31 @@
1
+ module Metacrunch
2
+ class SNR
3
+ class Section
4
+ class Field
5
+
6
+ attr_reader :name
7
+ attr_accessor :value
8
+
9
+ def initialize(name, value)
10
+ raise ArgumentError, "required Field#name not given" if name.nil?
11
+
12
+ @name = name
13
+ @value = value
14
+ end
15
+
16
+ # ------------------------------------------------------------------------------
17
+ # Serialization
18
+ # ------------------------------------------------------------------------------
19
+
20
+ def to_xml(builder)
21
+ if value.respond_to?(:to_xml)
22
+ value.to_xml(root: self.name, builder: builder, skip_instruct: true)
23
+ else
24
+ builder.tag!(self.name, self.value)
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,63 @@
1
+ module Metacrunch
2
+ class SNR
3
+ class Section
4
+
5
+ attr_reader :name
6
+
7
+ def initialize(name)
8
+ raise ArgumentError, "required Section#name not given" if name.nil?
9
+
10
+ @name = name
11
+ @fields = []
12
+ end
13
+
14
+ # ------------------------------------------------------------------------------
15
+ # Common API
16
+ # ------------------------------------------------------------------------------
17
+
18
+ #
19
+ # Adds a field
20
+ #
21
+ def add(field_name, value)
22
+ add_field(Field.new(field_name, value))
23
+ end
24
+
25
+ # ------------------------------------------------------------------------------
26
+ # Fields
27
+ # ------------------------------------------------------------------------------
28
+
29
+ #
30
+ # Return all fields.
31
+ #
32
+ # @return [Array<Metacrunch::SNR::Section::Field>]
33
+ #
34
+ def fields
35
+ @fields
36
+ end
37
+
38
+ #
39
+ # Adds a new field to this section.
40
+ #
41
+ # @param [Metacrunch::SNR::Section::Field] field
42
+ # @return [Metacrunch::SNR::Section::Field]
43
+ #
44
+ def add_field(field)
45
+ @fields << field
46
+ field
47
+ end
48
+
49
+ # ------------------------------------------------------------------------------
50
+ # Serialization
51
+ # ------------------------------------------------------------------------------
52
+
53
+ def to_xml(builder)
54
+ builder.tag!(self.name) do
55
+ @fields.each do |_field|
56
+ _field.to_xml(builder)
57
+ end
58
+ end
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,101 @@
1
+ module Metacrunch
2
+ #
3
+ # A SNR object (Simple Normalized Record) is a simple data structure
4
+ # that you can use as a target resource when performing data normalization routines.
5
+ # A DNSR record consists of unique sections. A section is unique identified by it's
6
+ # name. Each section can hold many fields that store the actual values.
7
+ #
8
+ # A SNR object can be transformed into XML or JSON to allow easy integration into
9
+ # existing tools and workflows.
10
+ #
11
+ # For example: If you normalize MAB XML data for use in a search engine you can
12
+ # use a SNR object to store your normalized values.
13
+ #
14
+ class SNR
15
+ require_relative "./snr/section"
16
+ require_relative "./snr/field"
17
+
18
+ # ------------------------------------------------------------------------------
19
+ # Common API
20
+ # ------------------------------------------------------------------------------
21
+
22
+ #
23
+ # Adds a field with a value to a section. If the section with the given name
24
+ # doesn't exists it will be created.
25
+ #
26
+ # @param [String] section_name
27
+ # @param [String] field_name
28
+ # @param [#to_s] value
29
+ #
30
+ def add(section_name, field_name, value)
31
+ section = self.section(section_name) || Section.new(section_name)
32
+ section.add(field_name, value)
33
+ add_section(section)
34
+ end
35
+
36
+ # ------------------------------------------------------------------------------
37
+ # Sections
38
+ # ------------------------------------------------------------------------------
39
+
40
+ #
41
+ # @return [Hash{String => Metacrunch::SNR::Section}]
42
+ # @private
43
+ #
44
+ def sections_struct
45
+ @sections_struct ||= {}
46
+ end
47
+ private :sections_struct
48
+
49
+ #
50
+ # Return all sections.
51
+ #
52
+ # @return [Array<Metacrunch::SNR::Section>]
53
+ #
54
+ def sections
55
+ sections_struct.values
56
+ end
57
+
58
+ #
59
+ # Get section by name.
60
+ #
61
+ # @param [String] name Name of the section
62
+ # @return [Metacrunch::SNR::Section, nil] section by name or nil if a section
63
+ # with the given name doesn't exists.
64
+ #
65
+ def section(name)
66
+ sections_struct[name]
67
+ end
68
+
69
+ #
70
+ # Adds / replaces a section. The name of the section is used as a unique identifier.
71
+ # Therefore if you add a section with a name that already exists, the new section
72
+ # will override the existing one.
73
+ #
74
+ # @param [Metacrunch::SNR::Section] section
75
+ # @return [Metacrunch::SNR::Section]
76
+ #
77
+ def add_section(section)
78
+ sections_struct[section.name] = section
79
+ end
80
+
81
+ # ------------------------------------------------------------------------------
82
+ # Serialization
83
+ # ------------------------------------------------------------------------------
84
+
85
+ #
86
+ # Transforms the SNR into XML.
87
+ #
88
+ # @return [String] The SNR as XML string.
89
+ #
90
+ def to_xml
91
+ builder = Builder::XmlMarkup.new(indent: 2)
92
+ builder.instruct!(:xml, :encoding => "UTF-8")
93
+ builder.snr do
94
+ sections.each do |_section|
95
+ _section.to_xml(builder)
96
+ end
97
+ end
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,33 @@
1
+ require_relative "../transformer"
2
+
3
+ module Metacrunch
4
+ class Transformer
5
+ class Step
6
+
7
+ def initialize(transformer)
8
+ @transformer = transformer
9
+ end
10
+
11
+ def perform
12
+ raise NotImplementedError, "You must implement .perform() in your rule sub-class"
13
+ end
14
+
15
+ def transformer
16
+ @transformer
17
+ end
18
+
19
+ def source
20
+ transformer.source
21
+ end
22
+
23
+ def target
24
+ transformer.target
25
+ end
26
+
27
+ def options
28
+ transformer.options
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ module Metacrunch
2
+ class Transformer
3
+ require_relative "./transformer/step"
4
+
5
+ attr_reader :source, :target, :options
6
+
7
+ def initialize(source:, target:, options: {})
8
+ @source = source
9
+ @target = target
10
+ @options = options
11
+ end
12
+
13
+ def transform(step_class = nil, &block)
14
+ if block_given?
15
+ Step.new(self).instance_eval(&block) # TODO: Benchmark this
16
+ else
17
+ raise ArgumentError, "You need to provide a STEP or a block" if step_class.nil?
18
+ step_class.new(self).perform
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Metacrunch
2
- VERSION = "2.1.0.pre1"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/metacrunch.rb CHANGED
@@ -1,16 +1,23 @@
1
1
  require "active_support"
2
2
  require "active_support/core_ext"
3
+ require "active_support/builder"
3
4
  require "parallel"
4
5
  require "rubygems"
5
6
  require "rubygems/package"
6
7
  require "thor"
7
- require "thor/group"
8
+ require "ox"
8
9
 
9
10
  begin
10
11
  require "pry"
11
12
  rescue LoadError ; end
12
13
 
13
14
  module Metacrunch
15
+ require_relative "./metacrunch/version"
16
+ require_relative "./metacrunch/cli"
17
+ require_relative "./metacrunch/command"
18
+ require_relative "./metacrunch/utils"
19
+ require_relative "./metacrunch/snr"
20
+ require_relative "./metacrunch/transformer"
14
21
 
15
22
  def self.load_plugins
16
23
  Gem.find_latest_files("metacrunch_plugin.rb").each do |path|
@@ -19,8 +26,3 @@ module Metacrunch
19
26
  end
20
27
 
21
28
  end
22
-
23
- require "metacrunch/version"
24
- require "metacrunch/cli"
25
- require "metacrunch/command"
26
- require "metacrunch/utils"
data/metacrunch.gemspec CHANGED
@@ -3,7 +3,7 @@ require File.expand_path("../lib/metacrunch/version", __FILE__)
3
3
  Gem::Specification.new do |s|
4
4
  s.authors = ["René Sprotte", "Michael Sievers", "Marcel Otto"]
5
5
  s.email = "r.sprotte@ub.uni-paderborn.de"
6
- s.summary = %q{Metadata processing toolkit for Ruby}
6
+ s.summary = %q{Data processing toolkit for Ruby}
7
7
  s.description = s.summary
8
8
  s.homepage = "http://github.com/ubpb/metacrunch"
9
9
  s.licenses = ["MIT"]
@@ -20,6 +20,8 @@ Gem::Specification.new do |s|
20
20
  s.required_ruby_version = ">= 2.2.0"
21
21
 
22
22
  s.add_dependency "activesupport", "~> 4.2", ">= 4.2.0"
23
+ s.add_dependency "builder", "~> 3.2", ">= 3.2.2"
23
24
  s.add_dependency "parallel", "~> 1.4", ">= 1.4.1"
24
25
  s.add_dependency "thor", "~> 0.19"
26
+ s.add_dependency "ox", "~> 2.1"
25
27
  end
data/spec/snr_spec.rb ADDED
@@ -0,0 +1,73 @@
1
+ describe Metacrunch::SNR do
2
+
3
+ let(:snr) { Metacrunch::SNR.new }
4
+
5
+
6
+ describe ".add" do
7
+ it "adds a field and creates a section if the section doesn't exists" do
8
+ expect {
9
+ snr.add("mysection", "myfield", "My Value")
10
+ }.to change { snr.sections.count }.by(1)
11
+ end
12
+
13
+ it "adds a field to an existsing section" do
14
+ snr.add_section(Metacrunch::SNR::Section.new("mysection"))
15
+
16
+ expect {
17
+ snr.add("mysection", "myfield", "My Value")
18
+ }.not_to change { snr.sections.count }
19
+ end
20
+ end
21
+
22
+ describe ".sections" do
23
+ let(:section1) { Metacrunch::SNR::Section.new("section1") }
24
+ let(:section2) { Metacrunch::SNR::Section.new("section2") }
25
+
26
+ before {
27
+ snr.add_section(section1)
28
+ snr.add_section(section2)
29
+ }
30
+
31
+ subject { snr.sections }
32
+
33
+ it "returns all sections" do
34
+ expect(snr.sections.count).to be(2)
35
+ end
36
+
37
+ it { is_expected.not_to be_empty }
38
+ it { is_expected.to include(section1) }
39
+ it { is_expected.to include(section2) }
40
+ end
41
+
42
+ describe ".section(name)" do
43
+ context "when section exists" do
44
+ let(:section1) { Metacrunch::SNR::Section.new("section1") }
45
+ before { snr.add_section(section1) }
46
+ subject { snr.section("section1") }
47
+
48
+ it { is_expected.not_to be_nil }
49
+ it { is_expected.to be(section1) }
50
+ end
51
+
52
+ context "when section doesn't exists" do
53
+ subject { snr.section("no_such_section") }
54
+
55
+ it { is_expected.to be_nil }
56
+ end
57
+ end
58
+
59
+ describe ".to_xml" do
60
+ before {
61
+ snr.add("section1", "title", "Foo Bar")
62
+ snr.add("section1", "artists", ["Sievers, Michael", "Sprotte, René"])
63
+ snr.add("section2", "link", {label: "Click here", url: "http://example.com"})
64
+ }
65
+
66
+ subject { snr.to_xml }
67
+
68
+ it { is_expected.not_to be_nil }
69
+ it { is_expected.not_to be_empty }
70
+ it { is_expected.to eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<snr>\n <section1>\n <title>Foo Bar</title>\n <artists type=\"array\">\n <artist>Sievers, Michael</artist>\n <artist>Sprotte, René</artist>\n </artists>\n </section1>\n <section2>\n <link>\n <label>Click here</label>\n <url>http://example.com</url>\n </link>\n </section2>\n</snr>\n") }
71
+ end
72
+
73
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metacrunch
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.pre1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - René Sprotte
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-04-23 00:00:00.000000000 Z
13
+ date: 2015-05-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -32,6 +32,26 @@ dependencies:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: 4.2.0
35
+ - !ruby/object:Gem::Dependency
36
+ name: builder
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '3.2'
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 3.2.2
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - "~>"
50
+ - !ruby/object:Gem::Version
51
+ version: '3.2'
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.2.2
35
55
  - !ruby/object:Gem::Dependency
36
56
  name: parallel
37
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +86,21 @@ dependencies:
66
86
  - - "~>"
67
87
  - !ruby/object:Gem::Version
68
88
  version: '0.19'
69
- description: Metadata processing toolkit for Ruby
89
+ - !ruby/object:Gem::Dependency
90
+ name: ox
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.1'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.1'
103
+ description: Data processing toolkit for Ruby
70
104
  email: r.sprotte@ub.uni-paderborn.de
71
105
  executables:
72
106
  - metacrunch
@@ -83,7 +117,16 @@ files:
83
117
  - bin/metacrunch
84
118
  - lib/metacrunch.rb
85
119
  - lib/metacrunch/cli.rb
120
+ - lib/metacrunch/cli/base.rb
121
+ - lib/metacrunch/cli/command_definition.rb
122
+ - lib/metacrunch/cli/command_registry.rb
123
+ - lib/metacrunch/cli/main.rb
86
124
  - lib/metacrunch/command.rb
125
+ - lib/metacrunch/snr.rb
126
+ - lib/metacrunch/snr/field.rb
127
+ - lib/metacrunch/snr/section.rb
128
+ - lib/metacrunch/transformer.rb
129
+ - lib/metacrunch/transformer/step.rb
87
130
  - lib/metacrunch/utils.rb
88
131
  - lib/metacrunch/utils/file_reader.rb
89
132
  - lib/metacrunch/utils/file_reader_result.rb
@@ -93,8 +136,9 @@ files:
93
136
  - spec/assets/archive.tar.gz
94
137
  - spec/assets/regular_file.txt
95
138
  - spec/assets/regular_file.txt.gz
96
- - spec/file_reader_spec.rb
139
+ - spec/snr_spec.rb
97
140
  - spec/spec_helper.rb
141
+ - spec/utils/file_reader_spec.rb
98
142
  homepage: http://github.com/ubpb/metacrunch
99
143
  licenses:
100
144
  - MIT
@@ -110,20 +154,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
154
  version: 2.2.0
111
155
  required_rubygems_version: !ruby/object:Gem::Requirement
112
156
  requirements:
113
- - - ">"
157
+ - - ">="
114
158
  - !ruby/object:Gem::Version
115
- version: 1.3.1
159
+ version: '0'
116
160
  requirements: []
117
161
  rubyforge_project:
118
- rubygems_version: 2.4.6
162
+ rubygems_version: 2.4.5
119
163
  signing_key:
120
164
  specification_version: 4
121
- summary: Metadata processing toolkit for Ruby
165
+ summary: Data processing toolkit for Ruby
122
166
  test_files:
123
167
  - spec/assets/archive.tar
124
168
  - spec/assets/archive.tar.gz
125
169
  - spec/assets/regular_file.txt
126
170
  - spec/assets/regular_file.txt.gz
127
- - spec/file_reader_spec.rb
171
+ - spec/snr_spec.rb
128
172
  - spec/spec_helper.rb
129
- has_rdoc:
173
+ - spec/utils/file_reader_spec.rb