mrt-ingest 0.0.4 → 0.0.5

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
- 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