Class: BepastyClient::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/bepasty-client/client.rb

Constant Summary collapse

BODY_SIZE =
128*1024

Instance Method Summary collapse

Constructor Details

#initialize(server, password: nil, verbose: false) ⇒ Client

Returns a new instance of Client.

Parameters:

  • server (String)

    bepasty server URL

  • password (String, nil) (defaults to: nil)
  • verbose (Boolean) (defaults to: false)


15
16
17
18
19
# File 'lib/bepasty-client/client.rb', line 15

def initialize(server, password: nil, verbose: false)
  @server = server
  @password = password
  @verbose = verbose
end

Instance Method Details

#setupObject

Fetch server settings



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/bepasty-client/client.rb', line 22

def setup
  http_start('/apis/rest') do |uri, http|
    res = http.get(uri)

    case res
    when Net::HTTPSuccess
      settings = JSON.parse(res.body)

      @max_file_size = settings['MAX_ALLOWED_FILE_SIZE']
      @max_body_size = settings.fetch('MAX_BODY_SIZE', BODY_SIZE)

      if @verbose
        puts "Max file size = #{@max_file_size}"
        puts "Max body size = #{@max_body_size}"
      end
    else
      raise Error, "Failed to query server settings: HTTP #{res.code}, #{res.message}"
    end
  end
end

#upload_io(io, filename: nil, content_type: nil, max_life: nil) ⇒ String

Upload file

Parameters:

  • io (IO)
  • filename (String, nil) (defaults to: nil)
  • content_type (String, nil) (defaults to: nil)
  • max_life (Hash, nil) (defaults to: nil)

Returns:

  • (String)

    file URL

Raises:



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/bepasty-client/client.rb', line 50

def upload_io(io, filename: nil, content_type: nil, max_life: nil)
  if filename.nil? && io.respond_to?(:path)
    filename = File.basename(io.path)
  end

  max_life ||= {unit: :days, value: 1}

  sent_bytes = 0
  transaction_id = nil
  file_location = nil

  if io.respond_to?(:size)
    send_io = io
  else
    send_io = StringIO.new(io.read)
    content_type = 'text/plain' if content_type.nil? && filename.nil?
  end

  if @max_file_size && send_io.size > @max_file_size
    raise Error, "File size #{send_io.size} exceeds server max file size of #{@max_file_size} bytes"
  end

  http_start('/apis/rest/items') do |uri, http|
    until send_io.eof?
      chunk = send_io.read(@max_body_size)

      req = Net::HTTP::Post.new(uri)
      req.basic_auth('bepasty', @password) if @password
      req['Content-Range'] = "bytes #{sent_bytes}-#{sent_bytes + chunk.size - 1}/#{send_io.size}"
      req['Transaction-ID'] = transaction_id if transaction_id
      req['Content-Type'] = content_type || ''
      req['Content-Filename'] = filename || ''
      req['Content-Length'] = send_io.size
      req['Maxlife-Unit'] = max_life[:unit].to_s.upcase
      req['Maxlife-Value'] = max_life[:value]

      req.body = Base64.encode64(chunk)

      if @verbose
        puts "Uploading chunk, Content-Range=#{req['Content-Range']}, Transaction-ID=#{transaction_id}"
      end

      res = http.request(req)

      case res
      when Net::HTTPSuccess
        if transaction_id.nil? && res['Transaction-ID']
          transaction_id = res['Transaction-ID']
        end

        file_location = res['Content-Location'] if res['Content-Location']
      else
        if res['Content-Type'] == 'application/json'
          err = JSON.parse(res.body)['error']
          raise Error, "bepasty error: code=#{err['code']}, message=#{err['message']}"
        else
          raise Error, "HTTP #{res.code}: #{res.message}"
        end
      end

      sent_bytes += chunk.size
    end
  end

  if file_location.nil?
    raise Error, 'Server did not disclose file location'
  end

  # bepasty returns REST item URL, we want web URL instead
  File.join(@server, file_location.split('/').last)
end