mrt-ingest 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: b29f8fd2bc7331b638a034dc11c86726ebb3f1526a62cb2d8b71f471215110cb
4
- data.tar.gz: f3797630caf8ebbda198e29590b85bdf4f01391b9d031472d5b3d950de9b836b
2
+ SHA1:
3
+ metadata.gz: 564379d9be6c8e4625b31c7960d31927edf00d8c
4
+ data.tar.gz: 9329f69b68d2235082bc6e030d7d44529080094c
5
5
  SHA512:
6
- metadata.gz: d1109ffa2df106b91e4fdef16a9b6fa2fa82305b34f56a5a189304c048490b8e56c868566f5fd2a7b64bdfdb243d65f54dd8625c059b5d1f743bd0f678af5f16
7
- data.tar.gz: 9c669cbc0180ddeef7b71649cc349c804cf29dc351a140827db5a9d8a24f6a88b0889e978a7e9d48fb40522bd7c634c593e69d78d07e7692a0e2af043124525e
6
+ metadata.gz: '0801ccf1a414ffdbb70882036771d4e63b2138274658873e65b3df68b8b3d8e26e2ebc004d18aed3042158300ef8a0cfc21d40b10302eb4138c7f80e96fa40f6'
7
+ data.tar.gz: d0e324c585de1f785c8d3c54bb0217ceedb0bece034fe6694b966b72cd0cc87d57fe231c71446d9f70eef4dcffff37ac4f3e7d71393270576a858a322ebe99cb
data/.gitignore CHANGED
@@ -4,6 +4,9 @@
4
4
  # Gemfile.lock should be checked in for apps, but not for libraries
5
5
  Gemfile.lock
6
6
 
7
+ # github-markdown-preview previews
8
+ *.md.html
9
+
7
10
  ###########################
8
11
  #### Generated ignores ####
9
12
 
@@ -69,7 +72,8 @@ build-iPhoneSimulator/
69
72
  .LSOverride
70
73
 
71
74
  # Icon must end with two \r
72
- Icon
75
+ Icon
76
+
73
77
 
74
78
  # Thumbnails
75
79
  ._*
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
+ --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build mrt-ingest-0.0.5.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove RDoc HTML files" fullCmd="clobber_rdoc" taksId="clobber_rdoc" /><RakeTask description="Build and install mrt-ingest-0.0.5.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install mrt-ingest-0.0.5.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Build RDoc HTML files" fullCmd="rdoc" taksId="rdoc" /><RakeTask description="Create tag v0.0.5 and build and push mrt-ingest-0.0.5.gem to rubygems.org" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="Rebuild RDoc HTML files" fullCmd="rerdoc" taksId="rerdoc" /><RakeTask description="Run tests" fullCmd="test" taksId="test" /><RakeTask description="" fullCmd="clobber" taksId="clobber" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="html" taksId="html" /><RakeTask description="" fullCmd="html/created.rid" taksId="html/created.rid" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Encoding" addBOMForNewFiles="with NO BOM" />
4
+ </project>
@@ -0,0 +1,18 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="ConvertOneChainedExprToSafeNavigation" enabled="true" level="INFORMATION" enabled_by_default="true" />
5
+ <inspection_tool class="GoNameStartsWithPackageName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
6
+ <inspection_tool class="GoSnakeCaseUsage" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
7
+ <inspection_tool class="GoUnusedGlobalVariable" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
8
+ <inspection_tool class="GoUnusedVariable" enabled="true" level="WARNING" enabled_by_default="true" />
9
+ <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
10
+ <inspection_tool class="RubyStringKeysInHashInspection" enabled="false" level="WARNING" enabled_by_default="false" />
11
+ <inspection_tool class="RubyTooManyInstanceVariablesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
12
+ <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
13
+ <option name="processCode" value="true" />
14
+ <option name="processLiterals" value="true" />
15
+ <option name="processComments" value="true" />
16
+ </inspection_tool>
17
+ </profile>
18
+ </component>
@@ -0,0 +1,32 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="GoImports">
4
+ <option name="optimizeImportsOnTheFly" value="false" />
5
+ </component>
6
+ <component name="NodePackageJsonFileManager">
7
+ <packageJsonPaths />
8
+ </component>
9
+ <component name="ProjectInspectionProfilesVisibleTreeState">
10
+ <entry key="Project Default">
11
+ <profile-state>
12
+ <expanded-state>
13
+ <State />
14
+ <State>
15
+ <id>Declaration redundancyGo</id>
16
+ </State>
17
+ <State>
18
+ <id>Go</id>
19
+ </State>
20
+ </expanded-state>
21
+ <selected-state>
22
+ <State>
23
+ <id>GoUnusedLabel</id>
24
+ </State>
25
+ </selected-state>
26
+ </profile-state>
27
+ </entry>
28
+ </component>
29
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="false" project-jdk-name="RVM: ruby-2.4.4" project-jdk-type="RUBY_SDK">
30
+ <output url="file://$PROJECT_DIR$/out" />
31
+ </component>
32
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/mrt-ingest-ruby.iml" filepath="$PROJECT_DIR$/mrt-ingest-ruby.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,87 @@
1
+ AllCops:
2
+ # Suppress complaints about post-2.0 syntax
3
+ TargetRubyVersion: 2.4
4
+ # Exclude IDEA coverage output
5
+ Exclude:
6
+ - 'out/**/*'
7
+
8
+ # Allow one line around block body (Layout/EmptyLines will still disallow two or more)
9
+ Layout/EmptyLinesAroundBlockBody:
10
+ Enabled: false
11
+
12
+ # Allow one line around class body (Layout/EmptyLines will still disallow two or more)
13
+ Layout/EmptyLinesAroundClassBody:
14
+ Enabled: false
15
+
16
+ # Allow one line around module body (Layout/EmptyLines will still disallow two or more)
17
+ Layout/EmptyLinesAroundModuleBody:
18
+ Enabled: false
19
+
20
+ # Make indents consistent regardless of the lengths of variables and method names and whatnot
21
+ Layout/MultilineMethodCallIndentation:
22
+ EnforcedStyle: indented
23
+
24
+ # Produces monsters
25
+ Layout/MultilineOperationIndentation:
26
+ Enabled: false
27
+
28
+ # Reasonable line-length check; it's too easy for the cure to be worse than the disease
29
+ Metrics/LineLength:
30
+ Max: 150
31
+
32
+ # Confusing and weird
33
+ Naming/VariableNumber:
34
+ Enabled: False
35
+
36
+ # We meant to do that
37
+ Naming/MemoizedInstanceVariableName:
38
+ Enabled: False
39
+
40
+ # It works in context, trust us
41
+ Naming/UncommunicativeMethodParamName:
42
+ Enabled: False
43
+
44
+ # Do what's readable in the context you're in
45
+ Style/AccessModifierDeclarations:
46
+ Enabled: false
47
+
48
+ # 👎 to cultural imperialism
49
+ Style/AsciiComments:
50
+ Enabled: false
51
+
52
+ # Sometimes we want to distinguish hash parameters from keyword arguments
53
+ Style/BracesAroundHashParameters:
54
+ Enabled: False
55
+
56
+ # Seriously?
57
+ Style/CommentedKeyword:
58
+ Enabled: False
59
+
60
+ # Disable problematic module documentation check (see https://github.com/bbatsov/rubocop/issues/947)
61
+ Style/Documentation:
62
+ Enabled: false
63
+
64
+ # Adding more line noise to format strings will not improve them
65
+ Style/FormatStringToken:
66
+ Enabled: false
67
+
68
+ # Putting '# frozen_string_literal: true' everywhere does not make the world a better place
69
+ Style/FrozenStringLiteralComment:
70
+ Enabled: false
71
+
72
+ # `foo.positive?` is cute, but it's not actually more readable than `foo > 0`
73
+ Style/NumericPredicate:
74
+ Enabled: false
75
+
76
+ # The semantics of `foo&.bar` are a lot less interchangeable with `foo && foo.bar` than RuboCop thinks
77
+ Style/SafeNavigation:
78
+ Enabled: false
79
+
80
+ # Requiring the lambda() method just makes wordy calls wordier
81
+ Style/Lambda:
82
+ EnforcedStyle: literal
83
+
84
+ # Unclear why it's a good idea to give parameters semantically meaningless names
85
+ Style/SingleLineBlockParams:
86
+ Enabled: false
87
+
@@ -0,0 +1,2 @@
1
+ 2.4.4
2
+
@@ -0,0 +1,25 @@
1
+ ## 0.0.5 (2019-05-17)
2
+
3
+ - Invalid arguments (nil required parameters, string URLs where `URI` objects are expected, etc.)
4
+ now raise `ArgumentError` instead of `IngestException`.
5
+ - Removes prefetch option from 0.0.3, which we weren't using, and which added complexity.
6
+
7
+ ### Developer notes
8
+
9
+ - Updates code for Ruby 2.4
10
+ - Adds RuboCop style checks
11
+ - Replaces Test::Unit with RSpec
12
+
13
+ ## 0.0.4 (2018-10-23)
14
+
15
+ - Updates `json` gem from `~> 1.5` to `~> 2.0`
16
+ - Updates `rest-client` gem from `~> 1.6` to `~> 2.0`
17
+
18
+ ## 0.0.3 (2018-10-23)
19
+
20
+ - Adds prefetch option for remote URLs
21
+ - Ensures one-time server is only started once
22
+
23
+ ## 0.0.2 (2011-12-19)
24
+
25
+ - First public release
data/Gemfile CHANGED
@@ -1,7 +1,4 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in mrt-ingest.gemspec
4
4
  gemspec
5
-
6
- # TODO: remove this (in favor of gemspec) once there's a 2.4-compatible release
7
- gem 'fakeweb', git: 'https://github.com/chrisk/fakeweb.git', ref: '2b08c1f'
@@ -0,0 +1,56 @@
1
+ # mrt-ingest (ruby)
2
+
3
+ [![Build Status](https://travis-ci.org/CDLUC3/mrt-ingest-ruby.svg?branch=master)](https://travis-ci.org/CDLUC3/mrt-ingest-ruby)
4
+
5
+ ## What?
6
+
7
+ A Ruby ingest client for [Merritt](https://merritt.cdlib.org/).
8
+
9
+ ## Install
10
+
11
+ ```
12
+ $ gem build mrt-ingest.gemspec
13
+ $ sudo gem install mrt-ingest-0.0.1.gem
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ The code below creates a new Merritt object with content consisting of two local files
19
+ and one remote URL. The object is submitted to Merritt as a manifest, with the manifest,
20
+ local files, and `mrt-erc.txt` made available to Ingest by an
21
+ [Mrt::Ingest::OneTimeServer](lib/mrt/ingest/one_time_server.rb)
22
+ -- a simple WEBrick-based server that finds itself an open port, serves each file from
23
+ a temporary directory, and when all files have been served, shuts down.
24
+
25
+ ```ruby
26
+ require 'mrt/ingest'
27
+
28
+ client = Mrt::Ingest::Client.new(
29
+ "http://merritt.cdlib.org/object/ingest",
30
+ USERNAME,
31
+ PASSWORD
32
+ )
33
+ ingest_profile = "demo_merritt_content"
34
+ user_agent = "me/My Name"
35
+
36
+ obj = Mrt::Ingest::IObject.new(
37
+ erc: {
38
+ "who" => "Doe, John",
39
+ "what" => "Hello, world",
40
+ "when/created" => "2011"
41
+ }
42
+ )
43
+ obj.add_component(File.new("/tmp/helloworld_a"))
44
+ obj.add_component(File.new("/tmp/helloworld_b"))
45
+ obj.add_component(
46
+ URI.parse("http://example.org/xxx"),
47
+ name: "helloworld_c",
48
+ digest: Mrt::Ingest::MessageDigest::MD5.new("6f5902ac237024bdd0c176cb93063dc4")
49
+ )
50
+
51
+ obj.start_ingest(client, ingest_profile, user_agent)
52
+ obj.finish_ingest # waits for all files to be served, then shuts down
53
+ ```
54
+
55
+ For a more detailed example, see the [Merritt::Atom](https://github.com/CDLUC3/mrt-dashboard/tree/master/lib/merritt/atom)
56
+ module of the Merritt dashboard.
data/Rakefile CHANGED
@@ -1,21 +1,40 @@
1
- # -*- ruby -*-
2
- require 'rake/testtask'
3
- require 'rdoc/task'
4
-
5
- require 'bundler'
6
- include Rake::DSL
7
- Bundler::GemHelper.install_tasks
8
-
9
- task :default => [:test]
10
- Rake::TestTask.new(:test) do |t|
11
- t.libs << 'lib' << 'test'
12
- t.pattern = 'test/**/test_*.rb'
13
- t.verbose = true
1
+ # ------------------------------------------------------------
2
+ # RSpec
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ namespace :spec do
8
+
9
+ desc 'Run all unit tests'
10
+ RSpec::Core::RakeTask.new(:unit) do |task|
11
+ task.rspec_opts = %w[--color --format documentation --order default]
12
+ task.pattern = 'unit/**/*_spec.rb'
13
+ end
14
+
15
+ task all: [:unit]
14
16
  end
15
17
 
16
- RDoc::Task.new do |rd|
17
- rd.title = "Merritt Ingest Client"
18
- rd.rdoc_files.include("README", "lib/**/*.rb")
18
+ desc 'Run all tests'
19
+ task spec: 'spec:all'
20
+
21
+ # ------------------------------------------------------------
22
+ # Coverage
19
23
 
20
- rd.options += ['-f', 'darkfish',]
24
+ desc 'Run all unit tests with coverage'
25
+ task :coverage do
26
+ ENV['COVERAGE'] = 'true'
27
+ Rake::Task['spec:unit'].execute
21
28
  end
29
+
30
+ # ------------------------------------------------------------
31
+ # RuboCop
32
+
33
+ require 'rubocop/rake_task'
34
+ RuboCop::RakeTask.new
35
+
36
+ # ------------------------------------------------------------
37
+ # Defaults
38
+
39
+ desc 'Run unit tests, check test coverage, run acceptance tests, check code style'
40
+ task default: %i[coverage rubocop]
@@ -1,16 +1 @@
1
- # Author:: Erik Hetzner (mailto:erik.hetzner@ucop.edu)
2
- # Copyright:: Copyright (c) 2011, Regents of the University of California
3
-
4
- module Mrt
5
- module Ingest
6
- autoload :Client, "mrt/ingest/client"
7
- autoload :IObject, "mrt/ingest/iobject"
8
- autoload :MessageDigest, "mrt/ingest/message_digest"
9
- autoload :OneTimeServer, "mrt/ingest/one_time_server"
10
- autoload :Request, "mrt/ingest/request"
11
- autoload :Response, "mrt/ingest/response"
12
-
13
- class IngestException < Exception
14
- end
15
- end
16
- end
1
+ Dir.glob(File.expand_path('ingest/*.rb', __dir__)).sort.each(&method(:require))
@@ -10,7 +10,7 @@ module Mrt
10
10
 
11
11
  # A client for ingesting objects into a Merritt.
12
12
  class Client
13
- def initialize(base_uri, username=nil, password=nil)
13
+ def initialize(base_uri, username = nil, password = nil)
14
14
  @base_uri = base_uri
15
15
  @username = username
16
16
  @password = password
@@ -18,19 +18,20 @@ module Mrt
18
18
 
19
19
  # Send a request to the client.
20
20
  def ingest(ingest_req)
21
- return Response.new(mk_rest_request(ingest_req).execute())
21
+ Response.new(mk_rest_request(ingest_req).execute)
22
22
  end
23
23
 
24
24
  # :nodoc:
25
25
  def mk_rest_request(ingest_req)
26
- args = {
27
- :method => :post,
28
- :url => @base_uri,
29
- :user => @username,
30
- :password => @password,
31
- :payload => ingest_req.mk_args(),
32
- :headers => { :multipart => true } }.delete_if { |k,v| (v.nil? || v == "") }
33
- return RestClient::Request.new(args)
26
+ args = {
27
+ method: :post,
28
+ url: @base_uri,
29
+ user: @username,
30
+ password: @password,
31
+ payload: ingest_req.mk_args,
32
+ headers: { multipart: true }
33
+ }.delete_if { |_k, v| (v.nil? || v == '') }
34
+ RestClient::Request.new(args)
34
35
  end
35
36
 
36
37
  end
@@ -0,0 +1,78 @@
1
+ require 'digest/md5'
2
+
3
+ module Mrt
4
+ module Ingest
5
+ # Represents a component of an object to ingest. Either a #URI or a
6
+ # #File.
7
+ class Component # :nodoc:
8
+
9
+ attr_reader :server, :uri
10
+
11
+ def initialize(server, location, options)
12
+ @server = server
13
+ @name = options[:name]
14
+ @digest = options[:digest]
15
+ @mime_type = options[:mime_type]
16
+ @size = options[:size]
17
+
18
+ init_uri(location)
19
+ end
20
+
21
+ class << self
22
+ def from_erc(server, erc)
23
+ return Component.new(server, erc, name: 'mrt-erc.txt') if erc.is_a?(URI) || erc.is_a?(File)
24
+ return from_hash(server, erc) if erc.is_a?(Hash)
25
+
26
+ raise ArgumentError, 'Bad ERC supplied: must be a URI, File, or Hash'
27
+ end
28
+
29
+ def from_hash(server, erc_h)
30
+ uri_str, path = server.add_file do |f|
31
+ f.write("erc:\n")
32
+ erc_h.each_pair { |k, v| f.write("#{k}: #{v}\n") }
33
+ end
34
+
35
+ digest = Mrt::Ingest::MessageDigest::MD5.from_file(File.new(path))
36
+ Component.new(server, URI.parse(uri_str), name: 'mrt-erc.txt', digest: digest)
37
+ end
38
+ end
39
+
40
+ def to_manifest_entry
41
+ "#{@uri} | #{digest_type} | #{digest_value} | #{@size} | | #{@name} | #{@mime_type}\n"
42
+ end
43
+
44
+ def digest_type
45
+ @digest && @digest.type
46
+ end
47
+
48
+ def digest_value
49
+ @digest && @digest.value
50
+ end
51
+
52
+ private
53
+
54
+ def file_like?(location)
55
+ [File, Tempfile].any? { |c| location.is_a?(c) }
56
+ end
57
+
58
+ def init_uri(location)
59
+ return init_from_file(location) if file_like?(location)
60
+ return init_from_uri(location) if location.is_a?(URI)
61
+
62
+ raise ArgumentError, "Trying to add a component that is not a File or URI: #{location}"
63
+ end
64
+
65
+ def init_from_file(file)
66
+ @name = File.basename(file.path) if @name.nil?
67
+ @uri = server.add_file(file)[0]
68
+ @digest = Mrt::Ingest::MessageDigest::MD5.from_file(file) if @digest.nil?
69
+ @size = File.size(file.path) if @size.nil?
70
+ end
71
+
72
+ def init_from_uri(uri)
73
+ @name = File.basename(uri.to_s) if @name.nil?
74
+ @uri = uri
75
+ end
76
+ end
77
+ end
78
+ end