Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
language: ruby
sudo: false
rvm:
- 2.2.2
before_install: gem install bundler -v 1.10.5
- 2.4.2
before_install:
- rvm @global do gem install bundler -v 1.12.5

gemfile:
- Gemfile

script:
bundle exec rake
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015 Winston Durand
Copyright (c) 2017 Alex Tsui

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
48 changes: 26 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
# Backblaze
# backblaze

The Backblaze ruby gem is an implementation of the [Backblaze B2 Cloud Storage API](https://www.backblaze.com/b2/docs/). In addition to simplifying calls, it also implements an object oriented structure for dealing with files. Calling the api through different objects will not cause each to get updated. Always assume that data retrieved is just a snapshot from when the object was retrieved.
The `paperclip` gem abstracts the [Backblaze B2 Cloud Storage API](https://www.backblaze.com/b2/docs/).
It was started by Winston Durand at [R167/backblaze](https://github.com/R167/backblaze).

## Installation
Backblaze B2 Cloud Storage is similar to Amazon's AWS S3 Storage, but it has a few selling points:

Add this line to your application's Gemfile:

```ruby
gem 'backblaze'
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install backblaze
1. They run their own hardware (that's open-sourced, including the schematics, and drive reports)
2. It's $0.005/GB/month vs S3's $0.030/GB/month
3. You actually get a free GB of bandwidth a day, so it might be nice for personal projects.

## Usage

TODO: Write usage instructions here
After fetching the repo and running bundle, run `bin/console` and do this:

## Development
```
# log in
> Backblaze::B2.login(account_id: "your_backblaze_account_id", application_key: "your_application_key")
# list buckets
> Backblaze::B2::Bucket.buckets
```

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
## Applications

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
This is used as a storage backend for Paperclip attachments in Rails. See [paperclip-backblaze](https://github.com/alextsui05/paperclip-backblaze)

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/backblaze. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.

Bug reports and pull requests are welcome on GitHub at
https://github.com/alextsui05/backblaze. This project is intended to be a safe,
welcoming space for collaboration, and contributors are expected to adhere to
the [Contributor Covenant](contributor-covenant.org) code of conduct.

## License

The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).

## Version Log

### 0.4.0

Officially hijacking the gem from R167 and bumping the version.
10 changes: 5 additions & 5 deletions backblaze.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ require 'backblaze/version'
Gem::Specification.new do |spec|
spec.name = "backblaze"
spec.version = Backblaze::VERSION
spec.authors = ["Winston Durand"]
spec.email = ["me@winstondurand.com"]
spec.authors = ["Alex Tsui", "Winston Durand"]
spec.email = ["alextsui05@gmail.com"]

spec.summary = %q{Interface for teh Backblaze B2 Cloud}
spec.description = %q{Intended to offer a way to interact with Backblaze B2 Cloud Storage without touching the API directly.}
spec.homepage = "https://github.com/R167/backblaze"
spec.summary = %q{Interface for the Backblaze B2 Cloud.}
spec.description = %q{Abstraction for the Backblaze B2 Cloud Storage API. Original by github.com:R167/backblaze}
spec.homepage = "https://github.com/alextsui05/backblaze"
spec.license = "MIT"

spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
Expand Down
69 changes: 27 additions & 42 deletions lib/backblaze/b2.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
require "backblaze/b2/base"
require "backblaze/b2/bucket"
require "backblaze/b2/file"
require "backblaze/b2/file_version"
require 'net/http'
require 'backblaze/b2/base'
require 'backblaze/b2/bucket'
require 'backblaze/b2/file'
require 'backblaze/b2/file_version'
require 'tempfile'
require 'digest/sha1'
require 'base64'

module Backblaze::B2
class << self
Expand All @@ -17,53 +17,38 @@ class << self
# @param [#to_s] application_key the private app key
# @raise [Backblaze::AuthError] when unable to authenticate
# @return [void]
def login(account_id:, application_key:, api_path: '/b2api/v1/')
options = {
basic_auth: {username: account_id, password: application_key}
def login(options)
api_path = options.fetch(:api_path) { '/b2api/v1/' }

params = {
headers: {
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => bearer(options)
}
}
api_path = "/#{api_path}/".gsub(/\/+/, '/')
response = HTTParty.get("https://api.backblazeb2.com#{api_path}b2_authorize_account", options)
raise Backblaze::AuthError.new(response) unless response.code == 200

response = HTTParty.get("https://api.backblazeb2.com#{api_path}b2_authorize_account", params)

raise Backblaze::AuthError, response unless response.success?

@account_id = response['accountId']
@token = response['authorizationToken']
@api_url = response['apiUrl']
@download_url = response['downloadUrl']
@api_path = api_path

Backblaze::B2::Base.base_uri "#{@api_url}#{api_path}"
Backblaze::B2::Base.headers 'Authorization' => @token, 'Content-Type' => 'application/json'
Backblaze::B2::Base.base_uri("#{@api_url}#{api_path}")
Backblaze::B2::Base.headers('Authorization' => token,
'Content-Type' => 'application/json')
end

def credentials_file(filename, raise_errors: true, logging: false)
opts = nil
open(filename, 'r') do |f|
if ::File.extname(filename) == '.json'
require 'json'
opts = JSON.load(f)
else
require 'psych'
opts = Psych.load(f.read)
end
end
parsed = {}
[:application_key, :account_id, :api_path].each do |key|
if opts[key.to_s].is_a? String
parsed[key] = opts[key.to_s]
end
end
if [:application_key, :account_id].inject(true) { |status, key| status && !parsed[key].nil? }
puts "Attempting #{parsed[:account_id]}" if logging
login(parsed)
true
else
puts "Missing params" if logging
false
end
rescue => e
puts e if logging
raise e if raise_errors
false
def bearer(options)
account_id = options.fetch(:account_id)
application_key = options.fetch(:application_key)
token = Base64.strict_encode64("#{account_id}:#{application_key}")

"Basic #{token}"
end
end
end
36 changes: 16 additions & 20 deletions lib/backblaze/b2/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class Base
# @!method put(path, options={}, &block)
# (see #get)

[:get, :head, :post, :put].each do |req|
define_method(req) do |path, options={}, &block|
%i[get head post put].each do |req|
define_method(req) do |path, options = {}, &block|
self.class.send(req, path, options, &block)
end
end
Expand All @@ -30,18 +30,20 @@ def file_versions(bucket_id:, convert:, limit:, double_check_server:, file_name:
retreive_count = (double_check_server ? 0 : -1)
files = file_list(bucket_id: bucket_id, limit: limit, retreived: retreive_count, file_name: file_name, first_file: nil, start_field: 'startFileId'.freeze)

files.map! do |f|
if block.nil?
Backblaze::B2::FileVersion.new(f)
else
block.call(f)
if convert
files.map! do |f|
if block.nil?
Backblaze::B2::FileVersion.new(f)
else
yield(f)
end
end
end if convert
end
files.compact
end

def file_list(limit:, retreived:, first_file:, start_field:, bucket_id:, file_name: nil, first: true)
params = {'bucketId'.freeze => bucket_id}
params = { 'bucketId'.freeze => bucket_id }
if limit == -1
params['maxFileCount'.freeze] = 1000
elsif limit > 1000
Expand All @@ -59,31 +61,25 @@ def file_list(limit:, retreived:, first_file:, start_field:, bucket_id:, file_na
params[start_field] = first_file
end

p params

response = post("/b2_list_file_#{start_field == 'startFileName' ? 'names' : 'versions'}", body: params.to_json)

raise Backblaze::FileError.new(response) unless response.code == 200
raise Backblaze::FileError, response unless response.code == 200

files = response['files'.freeze]
halt = false
files.map! do |f|
if halt
p f
nil
else
ret = Hash[f.map{|k,v| [Backblaze::Utils.underscore(k).to_sym, v]}]
p ret
if file_name && file_name != ret[:file_name]
halt = true
end
ret = Hash[f.map { |k, v| [Backblaze::Utils.underscore(k).to_sym, v] }]
halt = true if file_name && file_name != ret[:file_name]
halt ? nil : ret
end
end.compact!

retreived = retreived + files.size if retreived >= 0
retreived += files.size if retreived >= 0
if limit > 0
limit = limit - (retreived >= 0 ? files.size : 1000)
limit -= (retreived >= 0 ? files.size : 1000)
limit = 0 if limit < 0
end

Expand Down
Loading