ipfs-api 0.2.0 → 0.3.0

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
2
  SHA1:
3
- metadata.gz: 32a495dceb347f115f780d7356734ebe1fc5b55b
4
- data.tar.gz: 2343699171c0f73806649cfbf4b7e23e25255164
3
+ metadata.gz: 6b33b926a8240b157a5cfa1e14d35093d0f9a4ed
4
+ data.tar.gz: '0596fee2ce4d0a8a20226a1dbacb8bd47bdaf348'
5
5
  SHA512:
6
- metadata.gz: 71434462b2967da13a0c311bdfc3344e60460aebf60b1e690291789bad53fe73b20bf699fa8bba816b225cd95632746b65081699d11bd4c9d8b6858133909627
7
- data.tar.gz: d5d72049af5af1d706eba6bfee86d53f3e1950a7016531bc7ee793ff478a6d9dde28ab672eb6588e3a13fe23822885ab0a66568ee17d6ba2e22aa24daf0e3b2a
6
+ metadata.gz: 2723b6ec115c399d23c4fb0cc3fd4af506fcc83a3d2675a58f42139b755ef012563cb4bd4f81e34c6f2693016334548fa94bf819816f4ca5576a8314f329c074
7
+ data.tar.gz: 2849a2ef6807c906c622cd869b16a527b18965d433c9e0e9d5515e2c054d7aa8e653fcc0ac65b1d73e3e40bc96723bbbca8dfbd2df29c9df6841be18333ed28a
data/README.md CHANGED
@@ -1,71 +1,66 @@
1
1
  # Overview
2
2
 
3
- IPFS4R is a client library to access the [Interplanetary Filesystem (IPFS)](https://ipfs.io) from Ruby.
3
+ IPFS-API for Ruby is a client library to access the [Interplanetary Filesystem (IPFS)](https://ipfs.io) from Ruby.
4
4
 
5
5
  You can find more examples in the
6
6
  [examples directory](https://github.com/hjoest/ruby-ipfs-api/tree/master/examples).
7
7
 
8
8
  ## Installation
9
9
 
10
- Use ``gem`` to install it
10
+ You need an [IPFS daemon](https://ipfs.io/docs/install/) running
11
11
 
12
- ```bash
13
- gem install ipfs-api
14
- ```
12
+ ipfs daemon
13
+
14
+ To install this gem, run
15
+
16
+ gem install ipfs-api
15
17
 
16
18
  or simply add this line to your ``Gemfile``
17
19
 
18
- ```ruby
19
- gem 'ipfs-api', '~> 0.1.0'
20
- ```
20
+ gem 'ipfs-api', '~> 0.3.0'
21
21
 
22
22
  ## Basic examples
23
23
 
24
24
  This example will add a directory to *IPFS*. The directory ``data``
25
25
  must exist or otherwise an ``Errno::ENOENT`` error will be raised.
26
26
 
27
- ```ruby
28
- require 'ipfs-api'
27
+ require 'ipfs-api'
29
28
 
30
- ipfs = IPFS::Connection.new
31
- ipfs.add Dir.new('data')
32
- ```
29
+ ipfs = IPFS::Connection.new
30
+ ipfs.add Dir.new('data')
33
31
 
34
32
  Afterwards, we can retrieve what we put in.
35
- ```ruby
36
- require 'ipfs-api'
37
33
 
38
- ipfs = IPFS::Connection.new
34
+ require 'ipfs-api'
35
+
36
+ ipfs = IPFS::Connection.new
39
37
 
40
- # retrieve contents of a file
41
- print ipfs.cat('QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG')
38
+ # retrieve contents of a file
39
+ print ipfs.cat('QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG')
42
40
 
43
- # retrieve the whole directory
44
- ipfs.get('QmSh4Xjoy16v6XmnREE1yCrPM1dnizZc2h6LfrqXsnbBV7', 'copy-of-data')
45
- ```
41
+ # retrieve the whole directory and make a copy of it in ``copy-of-data``
42
+ ipfs.get('QmSh4Xjoy16v6XmnREE1yCrPM1dnizZc2h6LfrqXsnbBV7', 'copy-of-data')
46
43
 
47
44
  ## Advanced
48
45
 
49
46
  Dynamically add folders and files to *IPFS*, without creating them
50
47
  on the local file system:
51
48
 
52
- ```ruby
53
- require 'ipfs-api'
54
-
55
- ipfs = IPFS::Connection.new
56
- folder = IPFS::Upload.folder('test') do |test|
57
- test.add_file('hello.txt') do |fd|
58
- fd.write 'Hello'
59
- end
60
- test.add_file('world.txt') do |fd|
61
- fd.write 'World'
62
- end
63
- end
64
- ipfs.add folder do |node|
65
- # display each uploaded node:
66
- print "#{node.name}: #{node.hash}\n" if node.finished?
67
- end
68
- ```
49
+ require 'ipfs-api'
50
+
51
+ ipfs = IPFS::Connection.new
52
+ folder = IPFS::Upload.folder('test') do |test|
53
+ test.add_file('hello.txt') do |fd|
54
+ fd.write 'Hello'
55
+ end
56
+ test.add_file('world.txt') do |fd|
57
+ fd.write 'World'
58
+ end
59
+ end
60
+ ipfs.add folder do |node|
61
+ # display each uploaded node:
62
+ print "#{node.name}: #{node.hash}\n" if node.finished?
63
+ end
69
64
 
70
65
  ## License
71
66
 
data/Rakefile CHANGED
@@ -52,7 +52,7 @@ spec = Gem::Specification.new do |s|
52
52
  s.has_rdoc = true
53
53
  s.extra_rdoc_files = RDOC_FILES
54
54
  s.rdoc_options = RDOC_OPTIONS
55
- s.required_ruby_version = ">= 1.9.3"
55
+ s.required_ruby_version = ">= 2.0.0"
56
56
  end
57
57
 
58
58
  # also keep the gemspec up to date each time we package a tarball or gem
@@ -20,17 +20,15 @@ Gem::Specification.new do |s|
20
20
  "lib/ipfs-api/io.rb",
21
21
  "lib/ipfs-api/upload.rb",
22
22
  "lib/ipfs-api/version.rb",
23
- "test/common.rb",
24
23
  "test/samples.rb",
25
24
  "test/test_cmd_add.rb",
26
25
  "test/test_cmd_cat.rb",
27
26
  "test/test_cmd_get.rb",
28
27
  "test/test_cmd_id.rb",
29
28
  "test/test_cmd_ls.rb",
30
- "test/test_cmd_name.rb",
31
29
  "test/test_io.rb",
32
30
  "test/test_upload.rb"]
33
- s.full_name = "ipfs-api-0.2.0"
31
+ s.full_name = "ipfs-api-0.3.0"
34
32
  s.has_rdoc = true
35
33
  s.homepage = "http://hjoest.github.io/ruby-ipfs-api"
36
34
  s.licenses = ["MIT"]
@@ -38,11 +36,11 @@ Gem::Specification.new do |s|
38
36
  s.platform = "ruby"
39
37
  s.rdoc_options = ["--title", "Interplanetary File System for Ruby", "--quiet", "--main", "lib/ipfs-api.rb"]
40
38
  s.require_paths = ["lib"]
41
- s.required_ruby_version = ">= 1.9.3"
39
+ s.required_ruby_version = ">= 2.0.0"
42
40
  s.required_rubygems_version = ">= 0"
43
41
  s.rubyforge_project = "ipfs-api"
44
- s.rubygems_version = "2.4.8"
42
+ s.rubygems_version = "2.6.10"
45
43
  s.specification_version = 4
46
44
  s.summary = "Interplanetary File System for Ruby"
47
- s.version = "0.2.0"
45
+ s.version = "0.3.0"
48
46
  end
@@ -1,10 +1,10 @@
1
- # =IPFS4R - Interplanetary Filesystem Library for Ruby
1
+ # =IPFS API for Ruby
2
2
  # License:: MIT (see the LICENSE file)
3
3
  # Website:: https://hjoest.github.io/ruby-ipfs-api
4
4
  #
5
5
  # ==Introduction
6
6
  #
7
- # IPFS4R is an IPFS[https://ipfs.io] library for Ruby.
7
+ # IPFS API for Ruby is an IPFS[https://ipfs.io] library for Ruby.
8
8
  #
9
9
  require 'ipfs-api/version'
10
10
  require 'ipfs-api/io'
@@ -11,66 +11,70 @@ module IPFS
11
11
  end
12
12
 
13
13
  def add nodes, &block
14
- boundaries = [ generate_boundary ]
15
- headers = {
16
- 'Content-Disposition' => 'form-data: name="files"',
17
- 'Content-Type' => "multipart/form-data; boundary=#{boundaries[0]}"
18
- }
19
- walker = Upload::TreeWalker.depth_first(nodes)
14
+ boundary = generate_boundary
15
+ tree_walker = Upload::TreeWalker.depth_first(nodes)
20
16
  node_map = {}
21
- stream = IO::ReadFromWriterIO.new do |buf|
22
- next if walker.nil?
23
- begin
24
- node, depth = walker.next
25
- node_map[node.path] = node
26
- rescue StopIteration
27
- depth = -1
28
- walker = nil
29
- end
30
- while boundaries.size > depth+1 && boundary = boundaries.shift
31
- buf << %Q{\
32
- --#{boundary}--\r\n\
17
+ producer = IO::StreamProducer.new do |buf|
18
+ buf << %Q{\
19
+ --#{boundary}\r\n\
20
+ Content-Disposition: file; filename="root"\r\n\
21
+ Content-Type: application/x-directory\r\n\
33
22
  \r\n\
34
23
  \r\n\
35
24
  }
36
- end
37
- next if walker.nil?
38
- if node.folder?
39
- boundaries.unshift generate_boundary
40
- buf << %Q{\
41
- --#{boundaries[1]}\r\n\
42
- Content-Disposition: form-data; name="file"; filename="#{node.path}"\r\n\
43
- Content-Type: multipart/mixed; boundary=#{boundaries[0]}\r\n\
25
+ tree_walker.each do |node, depth|
26
+ node_map[node.path] = node
27
+ if node.folder?
28
+ buf << %Q{\
29
+ --#{boundary}\r\n\
30
+ Content-Disposition: file; filename="root#{node.path.gsub('/', '%2F')}"\r\n\
31
+ Content-Type: application/x-directory\r\n\
44
32
  \r\n\
45
33
  \r\n\
46
34
  }
47
- elsif node.file?
48
- buf << %Q{\
49
- --#{boundaries[0]}\r\n\
50
- Content-Disposition: file; filename="#{node.path}"\r\n\
35
+ elsif node.file?
36
+ buf << %Q{\
37
+ --#{boundary}\r\n\
38
+ Content-Disposition: file; filename="root#{node.path.gsub('/', '%2F')}"\r\n\
51
39
  Content-Type: application/octet-stream\r\n\
52
40
  \r\n\
53
41
  #{node.content}\r\n\
54
42
  }
55
- else
56
- raise "Unknown node type: #{node}"
43
+ else
44
+ raise "Unknown node type: #{node}"
45
+ end
57
46
  end
47
+ buf << %Q{\
48
+ --#{boundary}\r\n\
49
+ }
58
50
  end
59
- nodes = []
51
+ headers = {
52
+ 'Content-Type' => "multipart/form-data; boundary=#{boundary}"
53
+ }
54
+ stream = producer.stream
55
+ uploaded_nodes = []
60
56
  post("add?encoding=json&r=true&progress=true", stream, headers) do |chunk|
61
57
  next if chunk.empty?
62
- upload = JSON.parse(chunk)
58
+ upload = nil
59
+ begin
60
+ upload = JSON.parse(chunk)
61
+ rescue JSON::ParserError
62
+ end
63
+ next if upload.nil?
63
64
  path, bytes, hash = ['Name', 'Bytes', 'Hash'].map { |p| upload[p] }
65
+ next if not path.start_with?('root/')
66
+ path = path[4..-1]
64
67
  node = node_map[path]
68
+ next if not node
65
69
  node.bytes = bytes if bytes
66
70
  node.hash = hash if hash
67
71
  if block_given?
68
72
  block.call(node)
69
73
  elsif hash
70
- nodes << node
74
+ uploaded_nodes << node
71
75
  end
72
76
  end
73
- block_given? ? nil : nodes
77
+ block_given? ? nil : uploaded_nodes
74
78
  end
75
79
 
76
80
  def cat path
@@ -82,16 +86,16 @@ Content-Type: application/octet-stream\r\n\
82
86
  end
83
87
 
84
88
  def get path, destination = nil
85
- stream = IO::ReadFromWriterIO.new do |buf|
89
+ producer = IO::StreamProducer.new do |buf|
86
90
  post("get?arg=#{CGI.escape(path)}") do |chunk|
87
91
  buf << chunk
88
92
  end
89
93
  buf.close
90
94
  end
91
95
  if destination.nil?
92
- return stream
96
+ return producer.stream
93
97
  else
94
- return IO::Tar.extract(stream, destination)
98
+ return IO::Tar.extract(producer.stream, destination)
95
99
  end
96
100
  end
97
101
 
@@ -1,59 +1,28 @@
1
- require 'stringio'
1
+ require 'tempfile'
2
2
  require 'rubygems/package'
3
3
 
4
4
  module IPFS; end
5
5
  module IPFS::IO # :nodoc:
6
6
 
7
- class ReadFromWriterIO # :nodoc:
7
+ class StreamProducer # :nodoc:
8
8
 
9
9
  def initialize &block
10
10
  @block = block
11
- @stream = StringIO.new
12
- @d = @p = 0
13
- @eof = false
14
- fetch_data
15
11
  end
16
12
 
17
- def read length = nil, outbuf = ''
18
- return '' if length == 0
19
- outbuf.slice!(length..-1) if !length.nil?
20
- q = 0
21
- while @stream.size > 0
22
- s = @stream.size - @p
23
- s = [length - q, s].min if !length.nil?
24
- outbuf[q, s] = @stream.string[@p, s]
25
- @p, q = @p + s, q + s
26
- @eof = true if length.nil? and @p > 0 and @p == q
27
- break if q == length or @eof
28
- fetch_data if @stream.size == @p
13
+ def stream
14
+ io = Tempfile.new('ruby-ipfs')
15
+ begin
16
+ @block.call io
17
+ ensure
18
+ io.close
29
19
  end
30
- if length.nil? || outbuf.size < length
31
- @eof = true
32
- end
33
- if q == 0 and not length.nil?
34
- outbuf = nil
35
- end
36
- outbuf
37
- end
38
-
39
- def pos
40
- @d + @p
41
- end
42
-
43
- def eof?
44
- @eof
45
- end
46
-
47
- private
48
- def fetch_data
49
- @p, @d = 0, @d + @p
50
- @stream.string = ''
51
- @block.call @stream if not @stream.closed?
20
+ File.open(io.path, 'r')
52
21
  end
53
22
 
54
23
  end
55
24
 
56
- module Tar
25
+ module Tar # :nodoc:
57
26
 
58
27
  def extract stream, destination
59
28
  Gem::Package::TarReader.new(stream) do |tar|
@@ -63,8 +63,8 @@ module IPFS::Upload
63
63
 
64
64
  def inspect
65
65
  s = "<#{@name}"
66
- s << ":#{@bytes}" if @bytes
67
- s << ":#{@hash}" if @hash
66
+ s << ":#{@bytes}" if defined?(@bytes)
67
+ s << ":#{@hash}" if defined?(@hash)
68
68
  s << '>'
69
69
  end
70
70
 
@@ -1,4 +1,4 @@
1
1
  module IPFS
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
4
4
 
@@ -1,5 +1,19 @@
1
1
  require 'tmpdir'
2
- require 'test/common'
2
+ require 'minitest/autorun'
3
+ begin
4
+ Minitest.const_get('Test')
5
+ rescue
6
+ module Minitest
7
+ Test = Unit::TestCase
8
+ end
9
+ end
10
+ if ENV['DEBUG']
11
+ require 'byebug'
12
+ else
13
+ def byebug; end
14
+ end
15
+
16
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
17
  require 'ipfs-api/upload'
4
18
 
5
19
  module Samples
@@ -1,6 +1,6 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $:.unshift File.expand_path('..', __FILE__)
2
2
 
3
- require 'test/samples'
3
+ require 'samples'
4
4
  require 'ipfs-api'
5
5
 
6
6
  include IPFS
@@ -1,6 +1,6 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $:.unshift File.expand_path('..', __FILE__)
2
2
 
3
- require 'test/samples'
3
+ require 'samples'
4
4
  require 'ipfs-api'
5
5
 
6
6
  include IPFS
@@ -1,6 +1,6 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $:.unshift File.expand_path('..', __FILE__)
2
2
 
3
- require 'test/samples'
3
+ require 'samples'
4
4
  require 'ipfs-api'
5
5
 
6
6
  include IPFS
@@ -1,6 +1,6 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $:.unshift File.expand_path('..', __FILE__)
2
2
 
3
- require 'test/common'
3
+ require 'samples'
4
4
  require 'ipfs-api'
5
5
 
6
6
  include IPFS
@@ -1,6 +1,6 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $:.unshift File.expand_path('..', __FILE__)
2
2
 
3
- require 'test/samples'
3
+ require 'samples'
4
4
  require 'ipfs-api'
5
5
 
6
6
  include IPFS
@@ -1,22 +1,21 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $:.unshift File.expand_path('..', __FILE__)
2
2
 
3
- require 'test/samples'
3
+ require 'samples'
4
4
  require 'ipfs-api/io'
5
5
 
6
6
  include IPFS::IO
7
7
 
8
- class ReadFromWriterIOTest < Minitest::Test
8
+ class StreamProducerTest < Minitest::Test
9
9
 
10
10
  def setup
11
11
  @parts = Samples.some_byte_sequences
12
12
  enum = @parts.each
13
- @reader = ReadFromWriterIO.new do |writer|
14
- begin
15
- writer << enum.next
16
- rescue StopIteration
17
- writer.close
13
+ producer = StreamProducer.new do |writer|
14
+ enum.each do |part|
15
+ writer << part
18
16
  end
19
17
  end
18
+ @reader = producer.stream
20
19
  end
21
20
 
22
21
  def test_read_byte_wise
@@ -24,7 +23,6 @@ class ReadFromWriterIOTest < Minitest::Test
24
23
  while (byte = @reader.read(1))
25
24
  result << byte
26
25
  assert_equal result.size, @reader.pos
27
- assert_not_eof @reader
28
26
  end
29
27
  assert_eof @reader
30
28
  assert_equal @parts.join, result
@@ -1,6 +1,6 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
1
+ $:.unshift File.expand_path('..', __FILE__)
2
2
 
3
- require 'test/samples'
3
+ require 'samples'
4
4
  require 'ipfs-api/upload'
5
5
 
6
6
  class NodeTest < Minitest::Test
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ipfs-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Holger Joest
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-03 00:00:00.000000000 Z
11
+ date: 2017-02-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This is a client library to access the IPFS from Ruby
14
14
  email: holger@joest.org
@@ -30,14 +30,12 @@ files:
30
30
  - lib/ipfs-api/io.rb
31
31
  - lib/ipfs-api/upload.rb
32
32
  - lib/ipfs-api/version.rb
33
- - test/common.rb
34
33
  - test/samples.rb
35
34
  - test/test_cmd_add.rb
36
35
  - test/test_cmd_cat.rb
37
36
  - test/test_cmd_get.rb
38
37
  - test/test_cmd_id.rb
39
38
  - test/test_cmd_ls.rb
40
- - test/test_cmd_name.rb
41
39
  - test/test_io.rb
42
40
  - test/test_upload.rb
43
41
  homepage: http://hjoest.github.io/ruby-ipfs-api
@@ -57,7 +55,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
55
  requirements:
58
56
  - - ">="
59
57
  - !ruby/object:Gem::Version
60
- version: 1.9.3
58
+ version: 2.0.0
61
59
  required_rubygems_version: !ruby/object:Gem::Requirement
62
60
  requirements:
63
61
  - - ">="
@@ -65,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
63
  version: '0'
66
64
  requirements: []
67
65
  rubyforge_project: ipfs-api
68
- rubygems_version: 2.4.8
66
+ rubygems_version: 2.6.10
69
67
  signing_key:
70
68
  specification_version: 4
71
69
  summary: Interplanetary File System for Ruby
@@ -1,9 +0,0 @@
1
- gem 'minitest' if RUBY_VERSION =~ /^1\.9/
2
- require 'minitest/autorun'
3
- if ENV['DEBUG']
4
- require 'byebug'
5
- else
6
- def byebug; end
7
- end
8
-
9
- $:.unshift File.expand_path('../../lib', __FILE__)
@@ -1,22 +0,0 @@
1
- $:.unshift File.expand_path('../..', __FILE__)
2
-
3
- require 'test/common'
4
- require 'ipfs-api'
5
-
6
- include IPFS
7
-
8
- class CommandNameTest < Minitest::Test
9
-
10
- def test_name_resolve
11
- ipfs = Connection.new
12
- resolved = ipfs.name.resolve
13
- assert resolved.start_with?('/ipfs/Qm')
14
- end
15
-
16
- def test_name_resolve_with_id
17
- ipfs = Connection.new
18
- resolved = ipfs.name.resolve('ipfs.io')
19
- assert resolved.start_with?('/ipfs/Qm')
20
- end
21
-
22
- end