resync-client 0.1.2 → 0.2.1
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 +4 -4
- data/.gitignore +2 -0
- data/CHANGES.md +10 -0
- data/lib/resync/client.rb +63 -0
- data/lib/resync/client/http_helper.rb +90 -90
- data/lib/resync/client/mixins.rb +1 -0
- data/lib/resync/client/mixins/bitstream_resource.rb +26 -0
- data/lib/resync/client/mixins/bitstream_resource_list.rb +29 -0
- data/lib/resync/client/mixins/client_delegator.rb +38 -0
- data/lib/resync/client/mixins/downloadable.rb +36 -0
- data/lib/resync/client/mixins/link_client_delegate.rb +19 -0
- data/lib/resync/client/mixins/resource_client_delegate.rb +19 -0
- data/lib/resync/client/mixins/zipped_resource.rb +20 -0
- data/lib/resync/client/mixins/zipped_resource_list.rb +26 -0
- data/lib/resync/client/version.rb +1 -1
- data/lib/resync/client/zip.rb +1 -0
- data/lib/resync/client/zip/bitstream.rb +85 -0
- data/lib/resync/client/zip/zip_package.rb +78 -0
- data/lib/resync/client/zip/zip_packages.rb +59 -0
- data/lib/resync/extensions.rb +36 -0
- data/resync-client.gemspec +1 -1
- data/spec/acceptance/example_spec.rb +46 -0
- data/spec/data/resourcedump/changedump.xml +16 -0
- data/spec/data/simulator/capability-list.xml +2 -0
- data/spec/data/simulator/change-list.xml +2 -0
- data/spec/data/simulator/source-description.xml +2 -0
- data/spec/data/simulator/update.txt +1 -0
- data/spec/unit/resync/client/bitstream_spec.rb +84 -80
- data/spec/unit/resync/client/client_spec.rb +64 -3
- data/spec/unit/resync/client/{resync_extensions_spec.rb → extensions_spec.rb} +1 -6
- data/spec/unit/resync/client/http_helper_spec.rb +187 -185
- data/spec/unit/resync/client/zip_package_spec.rb +47 -32
- data/spec/unit/resync/client/zip_packages_spec.rb +42 -38
- data/spec/unit/resync/client/zipped_resource_list_spec.rb +61 -0
- metadata +35 -16
- data/lib/resync/client/bitstream.rb +0 -79
- data/lib/resync/client/client.rb +0 -58
- data/lib/resync/client/downloadable.rb +0 -35
- data/lib/resync/client/dump.rb +0 -26
- data/lib/resync/client/resync_extensions.rb +0 -85
- data/lib/resync/client/zip_package.rb +0 -66
- data/lib/resync/client/zip_packages.rb +0 -51
- data/spec/unit/resync/client/dump_spec.rb +0 -26
data/lib/resync/client/client.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require_relative 'version'
|
2
|
-
require_relative 'http_helper'
|
3
|
-
|
4
|
-
module Resync
|
5
|
-
|
6
|
-
# Utility class for retrieving HTTP content and parsing it as ResourceSync documents.
|
7
|
-
class Client
|
8
|
-
|
9
|
-
# ------------------------------------------------------------
|
10
|
-
# Initializer
|
11
|
-
|
12
|
-
# Creates a new +Client+
|
13
|
-
# @param helper [HTTPHelper] the HTTP helper. Defaults to a new HTTP helper with
|
14
|
-
# +resync-client VERSION+ as the User-Agent string.
|
15
|
-
def initialize(helper: HTTPHelper.new(user_agent: "resync-client #{VERSION}"))
|
16
|
-
@helper = helper
|
17
|
-
end
|
18
|
-
|
19
|
-
# ------------------------------------------------------------
|
20
|
-
# Public methods
|
21
|
-
|
22
|
-
# Gets the content of the specified URI and parses it as a ResourceSync document.
|
23
|
-
def get_and_parse(uri)
|
24
|
-
uri = Resync::XML.to_uri(uri)
|
25
|
-
raw_contents = get(uri)
|
26
|
-
doc = XMLParser.parse(raw_contents)
|
27
|
-
doc.client = self
|
28
|
-
doc
|
29
|
-
end
|
30
|
-
|
31
|
-
# Gets the content of the specified URI as a string.
|
32
|
-
# @param uri [URI, String] the URI to download
|
33
|
-
# @return [String] the content of the URI
|
34
|
-
def get(uri)
|
35
|
-
uri = Resync::XML.to_uri(uri)
|
36
|
-
@helper.fetch(uri: uri)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Gets the content of the specified URI and saves it to a temporary file.
|
40
|
-
# @param uri [URI, String] the URI to download
|
41
|
-
# @return [String] the path to the downloaded file
|
42
|
-
def download_to_temp_file(uri)
|
43
|
-
uri = Resync::XML.to_uri(uri)
|
44
|
-
@helper.fetch_to_file(uri: uri)
|
45
|
-
end
|
46
|
-
|
47
|
-
# Gets the content of the specified URI and saves it to the specified file,
|
48
|
-
# overwriting it if it exists.
|
49
|
-
# @param uri [URI, String] the URI to download
|
50
|
-
# @param path [String] the path to save the download to
|
51
|
-
# @return [String] the path to the downloaded file
|
52
|
-
def download_to_file(uri:, path:)
|
53
|
-
uri = Resync::XML.to_uri(uri)
|
54
|
-
@helper.fetch_to_file(path: path, uri: uri)
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'resync'
|
2
|
-
|
3
|
-
module Resync
|
4
|
-
|
5
|
-
# Adds +get+, +get_raw+, and +get_file+ methods, delegating
|
6
|
-
# to the injected client.
|
7
|
-
#
|
8
|
-
# @see Augmented#client
|
9
|
-
module Downloadable
|
10
|
-
# Delegates to {Client#get_and_parse} to get the contents of
|
11
|
-
# +:uri+ as a ResourceSync document
|
12
|
-
def get_and_parse # rubocop:disable Style/AccessorMethodName
|
13
|
-
client.get_and_parse(uri)
|
14
|
-
end
|
15
|
-
|
16
|
-
# Delegates to {Client#get} to get the contents of this +:uri+
|
17
|
-
def get # rubocop:disable Style/AccessorMethodName
|
18
|
-
client.get(uri)
|
19
|
-
end
|
20
|
-
|
21
|
-
# Delegates to {Client#download_to_temp_file} to download the
|
22
|
-
# contents of +:uri+ to a file.
|
23
|
-
def download_to_temp_file # rubocop:disable Style/AccessorMethodName
|
24
|
-
client.download_to_temp_file(uri)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Delegates to {Client#download_to_file} to download the
|
28
|
-
# contents of +:uri+ to the specified path.
|
29
|
-
# @param path [String] the path to download to
|
30
|
-
def download_to_file(path)
|
31
|
-
client.download_to_file(uri: uri, path: path)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
data/lib/resync/client/dump.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require_relative 'zip_packages'
|
2
|
-
|
3
|
-
module Resync
|
4
|
-
# Extends {ChangeDump} and {ResourceDump} to provide
|
5
|
-
# transparent access to the linked bitstream packages
|
6
|
-
module Dump
|
7
|
-
# Injects a +:zip_package+ method into each resource,
|
8
|
-
# downloading the (presumed) bitstream package to a
|
9
|
-
# temp file and returning it as a {ZipPackage}
|
10
|
-
def resources=(value)
|
11
|
-
super
|
12
|
-
resources.each do |r|
|
13
|
-
def r.zip_package
|
14
|
-
@zip_package ||= ZipPackage.new(download_to_temp_file)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# A list (downloaded lazily) of the {ZipPackage}s for each resource
|
20
|
-
# @return [ZipPackages] the zip packages for each resource
|
21
|
-
def zip_packages
|
22
|
-
@zip_packages ||= ZipPackages.new(resources)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'resync'
|
2
|
-
require_relative 'downloadable'
|
3
|
-
require_relative 'dump'
|
4
|
-
|
5
|
-
# Extensions to the core Resync classes to simplify retrieval
|
6
|
-
module Resync
|
7
|
-
|
8
|
-
# ------------------------------------------------------------
|
9
|
-
# Base classes
|
10
|
-
|
11
|
-
# Injects a {Client} that subclasses can use to fetch
|
12
|
-
# resources and links
|
13
|
-
#
|
14
|
-
# @!attribute [rw] client
|
15
|
-
# @return [Client] the injected {Client}. Defaults to
|
16
|
-
# a new {Client} instance.
|
17
|
-
class Augmented
|
18
|
-
attr_writer :client
|
19
|
-
|
20
|
-
def client
|
21
|
-
@client ||= Client.new
|
22
|
-
end
|
23
|
-
|
24
|
-
alias_method :base_links=, :links=
|
25
|
-
private :base_links=
|
26
|
-
|
27
|
-
# Adds a +:client+ method to each link, delegating
|
28
|
-
# to {#client}
|
29
|
-
def links=(value)
|
30
|
-
self.base_links = value
|
31
|
-
self.base_links = value
|
32
|
-
parent = self
|
33
|
-
links.each do |l|
|
34
|
-
l.define_singleton_method(:client) do
|
35
|
-
parent.client
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Adds a +:client+ method to each resource, delegating
|
42
|
-
# to {Augmented#client}
|
43
|
-
class BaseResourceList
|
44
|
-
alias_method :base_resources=, :resources=
|
45
|
-
private :base_resources=
|
46
|
-
|
47
|
-
# Adds a +:client+ method to each resource, delegating
|
48
|
-
# to {Augmented#client}
|
49
|
-
def resources=(value)
|
50
|
-
self.base_resources = value
|
51
|
-
parent = self
|
52
|
-
resources.each do |r|
|
53
|
-
r.define_singleton_method(:client) do
|
54
|
-
parent.client
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# ------------------------------------------------------------
|
61
|
-
# Resource and Link
|
62
|
-
|
63
|
-
# Includes the {Downloadable} module
|
64
|
-
class Resource
|
65
|
-
include Downloadable
|
66
|
-
end
|
67
|
-
|
68
|
-
# Includes the {Link} module
|
69
|
-
class Link
|
70
|
-
include Downloadable
|
71
|
-
end
|
72
|
-
|
73
|
-
# ------------------------------------------------------------
|
74
|
-
# ResourceDump and ChaneDump
|
75
|
-
|
76
|
-
# Includes the {Dump} module
|
77
|
-
class ResourceDump
|
78
|
-
include Dump
|
79
|
-
end
|
80
|
-
|
81
|
-
# Includes the {Dump} module
|
82
|
-
class ChangeDump
|
83
|
-
include Dump
|
84
|
-
end
|
85
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'rexml/document'
|
2
|
-
require 'zip'
|
3
|
-
require_relative 'bitstream'
|
4
|
-
|
5
|
-
module Resync
|
6
|
-
# A ZIP package of resources or changes, providing access to individual
|
7
|
-
# bitstreams based on the included manifest file.
|
8
|
-
#
|
9
|
-
class ZipPackage
|
10
|
-
|
11
|
-
# ------------------------------------------------------------
|
12
|
-
# Attributes
|
13
|
-
|
14
|
-
# @return [Zip::File] the ZIP file wrapped by this package
|
15
|
-
attr_reader :zipfile
|
16
|
-
|
17
|
-
# @return [ResourceDumpManifest, ChangeDumpManifest] the manifest
|
18
|
-
# for the ZIP package
|
19
|
-
attr_reader :manifest
|
20
|
-
|
21
|
-
# ------------------------------------------------------------
|
22
|
-
# Initializer
|
23
|
-
|
24
|
-
# Creates a new +ZipPackage+ for the specified file.
|
25
|
-
#
|
26
|
-
# @param zipfile [Zip::File, String] the ZIP file, or a path to it.
|
27
|
-
def initialize(zipfile)
|
28
|
-
self.zipfile = zipfile
|
29
|
-
end
|
30
|
-
|
31
|
-
# ------------------------------------------------------------
|
32
|
-
# Public methods
|
33
|
-
|
34
|
-
# Gets the bitstream for the specified resource. (Note that this
|
35
|
-
# does no validation; if the resource is not in the manifest, or
|
36
|
-
# the corresponding entry is not in the ZIP file, the behavior of
|
37
|
-
# the returned {Bitstream} is undefined.)
|
38
|
-
#
|
39
|
-
# @return [Bitstream] a bitstream wrapping the ZIP entry for the
|
40
|
-
# specified resource.
|
41
|
-
def bitstream_for(resource)
|
42
|
-
Bitstream.new(zipfile: @zipfile, resource: resource)
|
43
|
-
end
|
44
|
-
|
45
|
-
# Gets all bitstreams declared in the package manifest.
|
46
|
-
# @return [Array<Bitstream>] a list of all bitstreams in the package
|
47
|
-
def bitstreams
|
48
|
-
manifest.resources.map { |r| bitstream_for(r) }
|
49
|
-
end
|
50
|
-
|
51
|
-
# ------------------------------------------------------------
|
52
|
-
# Private methods
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def zipfile=(value)
|
57
|
-
zipfile = value.is_a?(Zip::File) ? value : Zip::File.open(value)
|
58
|
-
manifest_entry = zipfile.find_entry('manifest.xml')
|
59
|
-
fail "No manifest.xml found in zipfile #{zipfile.name}" unless manifest_entry
|
60
|
-
manifest_stream = manifest_entry.get_input_stream
|
61
|
-
@manifest = XMLParser.parse(manifest_stream)
|
62
|
-
@zipfile = zipfile
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Resync
|
2
|
-
# Lazily retrieves and caches the zip packages for the specified
|
3
|
-
# list of resources. The packages are cached to temporary files
|
4
|
-
# which are deleted on exit; if they are deleted while the
|
5
|
-
# interpreter is running, the behavior is undefined (but bad things
|
6
|
-
# are likely to happen).
|
7
|
-
class ZipPackages
|
8
|
-
include Enumerable
|
9
|
-
|
10
|
-
# Creates a new {ZipPackages} wrapper for the specified list
|
11
|
-
# of resources.
|
12
|
-
# @param resources [Array<Resource>] The list of resources to
|
13
|
-
# get zip packages for.
|
14
|
-
def initialize(resources)
|
15
|
-
@resources = resources
|
16
|
-
@packages = {}
|
17
|
-
end
|
18
|
-
|
19
|
-
# Gets the size of this list of packages.
|
20
|
-
# @return the size of the underlying array.
|
21
|
-
def size
|
22
|
-
@resources.size
|
23
|
-
end
|
24
|
-
|
25
|
-
# Gets the zip package at the specified index, downloading it
|
26
|
-
# if necessary.
|
27
|
-
#
|
28
|
-
# @return [ZipPackage] the zip package for the resource at the
|
29
|
-
# specified index in the underlying array.
|
30
|
-
def [](key)
|
31
|
-
resource = @resources[key]
|
32
|
-
package_for(resource)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Gets the zip package for the specified resource, downloading it
|
36
|
-
# if necessary.
|
37
|
-
# @return [ZipPackage] the package for the resource
|
38
|
-
def package_for(resource)
|
39
|
-
@packages[resource] ||= resource.zip_package
|
40
|
-
end
|
41
|
-
|
42
|
-
# Lazily iterates the given block for each zip package, downloading
|
43
|
-
# as necessary.
|
44
|
-
# @param &block [Block] The block to iterate
|
45
|
-
def each
|
46
|
-
@resources.lazy.each do |resource|
|
47
|
-
yield package_for(resource)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Resync
|
4
|
-
describe Dump do
|
5
|
-
it 'transparently extracts bitstreams' do
|
6
|
-
package_uri = URI('http://example.com/resourcedump.zip')
|
7
|
-
client = instance_double(Client)
|
8
|
-
expect(client).to receive(:download_to_temp_file).once.with(package_uri).and_return('spec/data/resourcedump/resourcedump.zip')
|
9
|
-
|
10
|
-
resource_dump = XMLParser.parse(File.read('spec/data/resourcedump/resourcedump.xml'))
|
11
|
-
resource_dump.client = client
|
12
|
-
|
13
|
-
zip_packages = resource_dump.zip_packages
|
14
|
-
expect(zip_packages.size).to eq(1)
|
15
|
-
|
16
|
-
zip_package = zip_packages[0]
|
17
|
-
expect(zip_package).to be_a(ZipPackage)
|
18
|
-
|
19
|
-
bitstreams = zip_package.bitstreams
|
20
|
-
expect(bitstreams.size).to eq(2)
|
21
|
-
|
22
|
-
stream1 = bitstreams[0]
|
23
|
-
expect(stream1.content).to eq(File.read('spec/data/resourcedump/resources/res1'))
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|