wetransfer 0.4.4 → 0.9.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +1 -2
  3. data/.rubocop.yml +1 -1
  4. data/.travis.yml +3 -2
  5. data/Guardfile +11 -0
  6. data/README.md +82 -39
  7. data/V2_README.md +53 -0
  8. data/examples/create_collection.rb +13 -0
  9. data/examples/create_transfer.rb +1 -1
  10. data/lib/we_transfer_client/board_builder.rb +33 -0
  11. data/lib/we_transfer_client/boards.rb +74 -0
  12. data/lib/we_transfer_client/future_board.rb +32 -0
  13. data/lib/we_transfer_client/future_file.rb +28 -0
  14. data/lib/we_transfer_client/future_link.rb +28 -0
  15. data/lib/we_transfer_client/future_transfer.rb +11 -5
  16. data/lib/we_transfer_client/remote_board.rb +47 -0
  17. data/lib/we_transfer_client/remote_file.rb +55 -0
  18. data/lib/we_transfer_client/remote_link.rb +9 -0
  19. data/lib/we_transfer_client/remote_transfer.rb +24 -1
  20. data/lib/we_transfer_client/transfer_builder.rb +3 -10
  21. data/lib/we_transfer_client/transfers.rb +73 -0
  22. data/lib/we_transfer_client/version.rb +2 -2
  23. data/lib/we_transfer_client.rb +86 -120
  24. data/spec/board_integration_spec.rb +68 -0
  25. data/spec/features/add_items_to_board_spec.rb +55 -0
  26. data/spec/features/create_board_spec.rb +46 -0
  27. data/spec/features/get_board_spec.rb +34 -0
  28. data/spec/features/transfer_spec.rb +41 -0
  29. data/spec/fixtures/Japan-01.jpg +0 -0
  30. data/spec/fixtures/Japan-02.jpg +0 -0
  31. data/spec/spec_helper.rb +20 -0
  32. data/spec/transfer_integration_spec.rb +54 -0
  33. data/spec/we_transfer_client/board_builder_spec.rb +66 -0
  34. data/spec/we_transfer_client/boards_spec.rb +56 -0
  35. data/spec/we_transfer_client/future_board_spec.rb +98 -0
  36. data/spec/we_transfer_client/future_file_spec.rb +48 -0
  37. data/spec/we_transfer_client/future_link_spec.rb +44 -0
  38. data/spec/we_transfer_client/future_transfer_spec.rb +30 -13
  39. data/spec/we_transfer_client/remote_board_spec.rb +92 -0
  40. data/spec/we_transfer_client/remote_file_spec.rb +91 -0
  41. data/spec/we_transfer_client/remote_link_spec.rb +33 -0
  42. data/spec/we_transfer_client/remote_transfer_spec.rb +101 -0
  43. data/spec/we_transfer_client/transfer_builder_spec.rb +48 -51
  44. data/spec/we_transfer_client/transfers_spec.rb +45 -0
  45. data/spec/we_transfer_client_spec.rb +51 -3
  46. data/wetransfer.gemspec +11 -5
  47. metadata +67 -27
  48. data/lib/we_transfer_client/future_file_item.rb +0 -16
  49. data/lib/we_transfer_client/future_web_item.rb +0 -18
  50. data/lib/we_transfer_client/remote_item.rb +0 -2
  51. data/spec/integration_spec.rb +0 -160
  52. data/spec/we_transfer_client/future_file_item_spec.rb +0 -39
  53. data/spec/we_transfer_client/future_web_item_spec.rb +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 23567d27a90247e6e713d476da4d81bb01e4bebe
4
- data.tar.gz: 3cec9fb058d7be32ffb779903f52a87fcc7f21c3
2
+ SHA256:
3
+ metadata.gz: b84e32a738e08a8e53b7959fe659a1d37c3bfba4cbde3fcf7760100aa46c2a10
4
+ data.tar.gz: 147c343eec0216e9208bd56554e0463441dbbe557b3a2623d1d737bcfaa48a54
5
5
  SHA512:
6
- metadata.gz: 30ec52713ad42fa38011232a1415618256d1e8c115c4da9e888eee1ad98df0658a997d42804b1044e297cecc0b2aa83e153919c491c12f8db620d94f5024af89
7
- data.tar.gz: f526ff9408367d99eac5ab4eb3dd40a8933d19f8caf9e344e928472ea33b29599e70850b7b966afdefbe2bb6c7f929c098a24c06467c015eb8bd0a50cc5acd74
6
+ metadata.gz: 44aa5cbf35ee63f81e33ca574b8b98bb02e21cd161796b01bb5003d92efaed4720711dd21e0d5438ae74cf82a971fccbe4770e950651a75ce8da5aef5a582ede
7
+ data.tar.gz: 1aee6811bd67ba882f106339b94860ec83d54e3ab9c2ef9a7c8b417f8b72a8c0e971d903a981895ed99d10d2c8d4a2421f9e1928998cb0b662ebb00d9dea79df
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
- --format progress
2
1
  --order rand
3
- --color
2
+ --color
data/.rubocop.yml CHANGED
@@ -1,2 +1,2 @@
1
1
  inherit_gem:
2
- wetransfer_style: ruby/default.yml
2
+ wetransfer_style: ruby/default.yml
data/.travis.yml CHANGED
@@ -1,8 +1,9 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.1.0
5
- - 2.5.1
4
+ - 2.3
5
+ - 2.4
6
+ - 2.5
6
7
  - jruby-9.0
7
8
  before_install: gem install bundler -v 1.16.1
8
9
  cache: bundler
data/Guardfile ADDED
@@ -0,0 +1,11 @@
1
+ group :red_green_refactor, halt_on_fail: true do
2
+ guard :rspec, cmd: 'bundle exec rspec' do
3
+ watch(%r{^spec/.+_spec\.rb$})
4
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
5
+ end
6
+
7
+ guard :rubocop, cmd: 'bundle exec rubocop' do
8
+ watch(%r{^lib/(.+)\.rb$})
9
+ watch(%r{^spec/(.+)\.rb$})
10
+ end
11
+ end
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # WeTransfer Ruby SDK
2
2
 
3
- An open source Ruby SDK for the WeTransfer Public API
3
+ The Ruby SDK that makes interacting with WeTransfer's Public API a breeze
4
+
5
+ This gem can be used to create transfers (as seen on WeTransfer.com) and boards (as seen in our [iOS app](https://itunes.apple.com/app/apple-store/id765359021?pt=10422800&ct=wetransfer-developer-portal&mt=8) and [Android app](https://play.google.com/store/apps/details?id=com.wetransfer.app.live&referrer=utm_source%3Dwetransfer%26utm_medium%3Ddeveloper-portal) ) alike.
4
6
 
5
7
  For your API key and additional info please visit our [developer portal](https://developers.wetransfer.com).
6
8
 
@@ -9,99 +11,140 @@ For your API key and additional info please visit our [developer portal](https:/
9
11
  ## Table of Contents
10
12
 
11
13
  1. [Installation](#installation)
12
- 2. [Usage](#usage)
13
- 3. [Super simple transfers](#super-simple-transfers)
14
- 4. [Development](#development)
15
- 5. [Contributing](#contributing)
16
- 6. [License](#license)
17
- 7. [Code of Conduct](#code-of-conduct)
14
+ 1. [Getting started](#getting-started)
15
+ 1. [Transfers](#transfers)
16
+ 1. [Boards](#boards)
17
+ 1. [Development](#development)
18
+ 1. [Contributing](#contributing)
19
+ 1. [License](#license)
20
+ 1. [Code of Conduct](#code-of-conduct)
18
21
 
19
22
  ## Installation
20
23
 
21
24
  Add this line to your application's Gemfile:
22
25
 
23
26
  ```ruby
24
- gem 'wetransfer'
27
+ gem 'wetransfer', version: '0.9.0.beta1'
25
28
  ```
26
29
 
27
30
  And then execute:
28
31
 
29
- $ bundle
32
+ bundle install
30
33
 
31
34
  Or install it yourself as:
32
35
 
33
- $ gem install wetransfer
34
-
35
- ## Usage
36
+ gem install wetransfer
36
37
 
37
- ### Minimalist transfers
38
+ ## Getting started
38
39
 
39
40
  You'll need to retrieve an API key from [our developer portal](https://developers.wetransfer.com).
40
41
 
41
- Be sure to not commit this key to Github! If you do though, no worries, you can always revoke & create a new key from within the portal.
42
+ Be sure to not commit this key to Github! If you do though, you can always revoke it and create a new key from within the portal.
42
43
 
43
- For configuring and storing secrets - like this API key - there are a variety of solutions. The smoothest here is creating a .env file:
44
+ For configuring and storing secrets - like this API key - there are a variety of solutions. The smoothest here is creating a `.env` file, and use a gem like [dotenv](https://github.com/bkeepers/dotenv).
44
45
 
45
46
  Now that you've got a wonderful WeTransfer API key, create a .env file in your project folder:
46
47
 
47
- $ touch .env
48
+ touch .env
49
+
50
+ You don't want the contents of this file to leave your system. Ever.
51
+
52
+ If the `.env` file is new, make sure to add it to your `.gitignore`, using the following command:
53
+
54
+ echo .env >> .gitignore
48
55
 
49
- Check your `.gitignore` file and make sure it has `.env` listed!
56
+ Open the file in your text editor and add this line:
50
57
 
51
- Now, open the file in your text editor and add this line:
58
+ WT_API_KEY=<your api key>
52
59
 
53
- `WT_API_KEY=<your api key>` (without the <> brackets!)
60
+ Make sure to replace `<your api key>` by your actual api key. Don't include the pointy brackets!
54
61
 
55
- Great! Now you can go to your project file and create the client:
62
+ Great! Now you can go to your project file and use the client.
63
+
64
+ ## Transfers
65
+
66
+ A transfer is a collection of files that can be created once, and downloaded until it expires. Once a transfer is ready for sharing, it is closed for modifications.
56
67
 
57
68
  ```ruby
58
69
  # In your project file:
59
70
  require 'we_transfer_client'
60
71
 
61
- @client = WeTransferClient.new(api_key: ENV.fetch('WT_API_KEY'))
72
+ client = WeTransfer::Client.new(api_key: ENV.fetch('WT_API_KEY'))
62
73
  ```
63
74
 
64
- Now that you've got the client set up you can use `create_transfer` to, well, create a transfer!
75
+ Now that you've got the client set up you can use `create_transfer_and_upload_files` to, well, create a transfer, and upload all files!
65
76
 
66
77
  ```ruby
67
- transfer = @client.create_transfer(name: "My wonderful transfer", description: "I'm so excited to share this") do |upload|
78
+ transfer = client.create_transfer_and_upload_files(message: 'All the Things') do |upload|
68
79
  upload.add_file_at(path: '/path/to/local/file.jpg')
69
80
  upload.add_file_at(path: '/path/to/another/local/file.jpg')
70
- upload.add_file(name: 'README.txt', io: StringIO.new("This is the contents of the file"))
71
- upload.add_web_url(url: "https://www.the.url.you.want.to.share.com", title: "title of the url"))
81
+ upload.add_file(name: 'README.txt', io: StringIO.new("You should read All the Things!"))
72
82
  end
73
83
 
74
- transfer.shortened_url => "https://we.tl/SSBsb3ZlIHJ1Ynk="
84
+ # To get a link to your transfer, call `url` on your transfer object:
85
+ transfer.url => "https://we.tl/t-123234="
75
86
  ```
76
87
 
77
- The upload will be performed at the end of the block.
88
+ The upload will be performed at the end of the block. Depending on your file sizes and network connection speed, this might take some time.
89
+
90
+ What are you waiting for? Open that link in your browser! Chop chop.
91
+
92
+ ## Boards
93
+
94
+ A board is a collection of files and links, but it is open for modifications. Like your portfolio: While working, you can make adjustments to it. A board is a fantastic place for showcasing your work in progress.
95
+
96
+ Boards need a WeTransfer Client to be present, just like transfers.
97
+
98
+ ```ruby
99
+ # In your project file:
100
+ require 'we_transfer_client'
101
+
102
+ client = WeTransfer::Client.new(api_key: ENV.fetch('WT_API_KEY'))
103
+ ```
104
+
105
+ After you create your client, you can
106
+
107
+ ### Create a board and upload items
108
+
109
+
110
+ ```ruby
111
+ board = client.create_board(name: 'Meow', description: 'On Cats') do |items|
112
+ items.add_file(name: 'big file.jpg', io: File.open('/path/to/huge_file.jpg', 'rb')items.add_file_at(path: '/path/to/another/file.txt')
113
+ items.add_web_url(url: 'http://wepresent.wetransfer.com', title: 'Time well spent')
114
+ end
115
+
116
+ puts board.url # => "https://we.tl/b-923478"
117
+ ```
118
+
119
+ You've just created a board. It is visible on the internet, to share it with anyone.
78
120
 
79
121
  ## Development
122
+
80
123
  You'll need to retrieve an API key from [our developer portal](https://developers.wetransfer.com), and as described above, store it in a local `.env` file. As always, do not commit this file to github! :)
81
124
 
82
125
  After forking and cloning down the repo, run `bundle install` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
83
126
 
84
- ```
85
- $ git clone <your fork>
86
- $ cd wetransfer_ruby_sdk
87
- $ bundle install
88
- ```
127
+ git clone <your fork> ./wetransfer_ruby_sdk
128
+ cd wetransfer_ruby_sdk
129
+ bundle install
89
130
 
90
131
  To install this gem onto your local machine, run `bundle exec rake install`.
91
132
 
92
133
  To execute to ruby specs, run:
93
134
 
94
- ```
95
- $ bundle exec rspec
96
- ```
135
+ bundle exec rspec
97
136
 
98
137
  Please note that we use rubocop to lint this gem -- be sure to run it prior to submitting a PR for maximum mergeability.
99
138
 
100
- $ bundle exec rubocop
139
+ bundle exec rubocop
140
+
141
+ If any violations can be handled by rubocop, you can run auto-fix and it'll handle them for you, though do run the tests again and make sure it hasn't done something... unexpected.
142
+
143
+ bundle exec rubocop -a
101
144
 
102
- If any violations can be handled by rubocop, you can run auto-fix and it'll handle them for you, though do run the tests again and make sure it hasn't done something ... unexpected.
145
+ For more convenience you also can run Guard, this checks all the tests and runs rubocop every time you save your files.
103
146
 
104
- $ bundle exec rubocop -a
147
+ bundle exec guard
105
148
 
106
149
  Hooray!
107
150
 
@@ -115,4 +158,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
115
158
 
116
159
  ## Code of Conduct
117
160
 
118
- Everyone interacting in the WeTransfer Ruby SDK project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/WeTransfer/wetransfer_ruby_sdk/blob/master/.github/CODE_OF_CONDUCT.md).
161
+ Everyone interacting in the WeTransfer Ruby SDK project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/WeTransfer/wetransfer_ruby_sdk/blob/master/.github/CODE_OF_CONDUCT.md).
data/V2_README.md ADDED
@@ -0,0 +1,53 @@
1
+ The process
2
+
3
+ In the v2 version of the Ruby SDK we have added a new feature, mutable transfers called boards.
4
+
5
+ Boards excists next to the transfers and will be mutable, so you can add new files or web_links to your board.
6
+
7
+
8
+ To use the ruby sdk you have to Initailize a new client with your API-Key:
9
+
10
+ ```
11
+ client = WeTransfer::Client.new(api_key: 'your-special-api-key')
12
+ ```
13
+
14
+ ### Initailize a Board
15
+
16
+ Once you created that new client you can call methods to create a new board, empty or as a block:
17
+
18
+ ```
19
+ board = client.create_board(name: 'File Collection', description: 'A collection of files')
20
+ ```
21
+ or:
22
+ ```
23
+ board = client.create_board(name: 'Dog Collection', description: 'A collection of dogs') do |item|
24
+ item.add_file(name: 'dalmatian.jpg', io: File.open('path/to/dalmatian.jpg', 'r'))
25
+ item.add_file(name: 'beagle.jpg', io: File.open('path/to/beagle.jpg', 'r'))
26
+ item.add_file(name: 'great_dane.jpg', io: File.open('path/to/great_dane.jpg', 'r'))
27
+ item.add_web_url(url: 'http://www.wetransfer.com', title: 'WeTransfer Website')
28
+ end
29
+ ```
30
+
31
+ ### Initialize a Transfer
32
+
33
+ For initializing a transfer the process is like this:
34
+
35
+ ```ruby
36
+ transfer = @client.create_transfer(name: "Dog transfer", description: "Have a look at my dogs") do |upload|
37
+ upload.add_file(name: 'chihuahua.jpg', io: File.open('path/to/chihuahua.jpg', 'r'))
38
+ upload.add_file(name: 'chow_chow.jpg', io: File.open('path/to/chow_chow.jpg', 'r'))
39
+ end
40
+
41
+ transfer.shortened_url => "https://we.tl/SSBsb3ZlIHJ1Ynk="
42
+ ```
43
+
44
+ Note: For initializing a transfer you have to pass all the files directly so the backend knows what you are uploading.
45
+
46
+
47
+
48
+ ### uploading the files
49
+
50
+ For both the transfer and board, the files are not in you transfer or collection, yet.
51
+
52
+ The files need to be uploaded and finalized
53
+
@@ -0,0 +1,13 @@
1
+ require_relative 'we_transfer_client'
2
+ require 'dotenv'
3
+ Dotenv.load
4
+
5
+ client = WeTransfer::Client.new(api_key: ENV.fetch('WT_API_KEY'))
6
+ transfer = client.create_transfer(name: 'My amazing transfer', description: 'Hi there!') do |builder|
7
+ builder.add_file(name: File.basename(__FILE__), io: File.open(__FILE__, 'rb'))
8
+ builder.add_file(name: 'amazing.txt', io: StringIO.new('This is unbelievable'))
9
+ builder.add_file(name: 'huge.bin', io: File.open('/path/to/local/file.jpg', 'rb'))
10
+ builder.add_file_at(path: __FILE__)
11
+ end
12
+
13
+ puts transfer.shortened_url
@@ -2,7 +2,7 @@ require_relative 'we_transfer_client'
2
2
  require 'dotenv'
3
3
  Dotenv.load
4
4
 
5
- client = WeTransferClient.new(api_key: ENV.fetch('WT_API_KEY')) # , logger: Logger.new($stderr))
5
+ client = WeTransfer::Client.new(api_key: ENV.fetch('WT_API_KEY'))
6
6
  transfer = client.create_transfer(name: 'My amazing transfer', description: 'Hi there!') do |builder|
7
7
  builder.add_file(name: File.basename(__FILE__), io: File.open(__FILE__, 'rb'))
8
8
  builder.add_file(name: 'amazing.txt', io: StringIO.new('This is unbelievable'))
@@ -0,0 +1,33 @@
1
+ class BoardBuilder
2
+ attr_reader :items
3
+ class TransferIOError < StandardError; end
4
+
5
+ def initialize
6
+ @items = []
7
+ end
8
+
9
+ def add_file(name:, io:)
10
+ ensure_io_compliant!(io)
11
+ @items << FutureFile.new(name: name, io: io)
12
+ end
13
+
14
+ def add_file_at(path:)
15
+ add_file(name: File.basename(path), io: File.open(path, 'rb'))
16
+ end
17
+
18
+ def add_web_url(url:, title: url)
19
+ @items << FutureLink.new(url: url, title: title)
20
+ end
21
+
22
+ private
23
+
24
+ def ensure_io_compliant!(io)
25
+ io.seek(0)
26
+ io.read(1) # Will cause things like Errno::EACCESS to happen early, before the upload begins
27
+ io.seek(0) # Also rewinds the IO for later uploading action
28
+ size = io.size # Will cause a NoMethodError
29
+ raise TransferIOError, "#{File.basename(io)}, given to add_file has a size of 0" if size <= 0
30
+ rescue NoMethodError
31
+ raise TransferIOError, "#{File.basename(io)}, given to add_file must respond to seek(), read() and size(), but #{io.inspect} did not"
32
+ end
33
+ end
@@ -0,0 +1,74 @@
1
+ module WeTransfer
2
+ class Client
3
+ module Boards
4
+ def create_board_and_upload_items(name:, description:, &block)
5
+ future_board = create_feature_board(name: name, description: description, &block)
6
+ remote_board = create_remote_board(board: future_board)
7
+ remote_board.files.each do |file|
8
+ check_for_file_duplicates(future_board.files, file)
9
+ local_file = future_board.files.select { |x| x.name == file.name }.first
10
+ upload_file(object: remote_board, file: file, io: local_file.io)
11
+ complete_file!(object: remote_board, file: file)
12
+ end
13
+ remote_board
14
+ end
15
+
16
+ def get_board(board:)
17
+ request_board(board: board)
18
+ end
19
+
20
+ private
21
+
22
+ def create_board(name:, description:, &block)
23
+ future_board = create_feature_board(name: name, description: description, &block)
24
+ create_remote_board(board: future_board)
25
+ end
26
+
27
+ def add_items(board:, board_builder_class: BoardBuilder)
28
+ builder = board_builder_class.new
29
+ yield(builder)
30
+ add_items_to_remote_board(items: builder.items, remote_board: board)
31
+ rescue LocalJumpError
32
+ raise ArgumentError, 'No items where added to the board'
33
+ end
34
+
35
+ def create_feature_board(name:, description:, future_board_class: FutureBoard, board_builder_class: BoardBuilder)
36
+ builder = board_builder_class.new
37
+ yield(builder) if block_given?
38
+ future_board_class.new(name: name, description: description, items: builder.items)
39
+ end
40
+
41
+ def create_remote_board(board:, remote_board_class: RemoteBoard)
42
+ authorize_if_no_bearer_token!
43
+ response = faraday.post(
44
+ '/v2/boards',
45
+ JSON.pretty_generate(board.to_initial_request_params),
46
+ auth_headers.merge('Content-Type' => 'application/json')
47
+ )
48
+ ensure_ok_status!(response)
49
+ remote_board = remote_board_class.new(JSON.parse(response.body, symbolize_names: true))
50
+ board.items.any? ? add_items_to_remote_board(items: board.items, remote_board: remote_board) : remote_board
51
+ end
52
+
53
+ def add_items_to_remote_board(items:, remote_board:)
54
+ items.group_by(&:class).each do |_, grouped_items|
55
+ grouped_items.each do |item|
56
+ item.add_to_board(client: self, remote_board: remote_board)
57
+ end
58
+ end
59
+ remote_board
60
+ end
61
+
62
+ def request_board(board:, remote_board_class: RemoteBoard)
63
+ authorize_if_no_bearer_token!
64
+ response = faraday.get(
65
+ "/v2/boards/#{board.id}",
66
+ {},
67
+ auth_headers.merge('Content-Type' => 'application/json')
68
+ )
69
+ ensure_ok_status!(response)
70
+ remote_board_class.new(JSON.parse(response.body, symbolize_names: true))
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,32 @@
1
+ class FutureBoard
2
+ attr_reader :name, :description, :items
3
+
4
+ def initialize(name:, description: nil, items: [])
5
+ @name = name
6
+ @description = description
7
+ @items = items
8
+ end
9
+
10
+ def files
11
+ @items.select { |item| item.class == FutureFile }
12
+ end
13
+
14
+ def links
15
+ @items.select { |item| item.class == FutureLink }
16
+ end
17
+
18
+ def to_initial_request_params
19
+ {
20
+ name: name,
21
+ description: description,
22
+ }
23
+ end
24
+
25
+ def to_request_params
26
+ {
27
+ name: name,
28
+ description: description,
29
+ items: items.map(&:to_request_params),
30
+ }
31
+ end
32
+ end