cloudapp-export 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1579ad02b2a2789e95e6e5c743765006091e9c67
4
- data.tar.gz: bfac4398babc3afc70aa4d1a44c57085128c0d52
2
+ SHA256:
3
+ metadata.gz: 76ec7d3deb5e44184022937ced41ddc7438bfebbb6729225de2476b7d647aa58
4
+ data.tar.gz: 1b967386965f333aa271ac6f2928c5c524849d4871379fa24b39392aae02a43c
5
5
  SHA512:
6
- metadata.gz: d20379fcab2828e82ee1e70e6fd35c246c9f00804b9b85a78a7e2fe680ae278d1c6e32c9905ab0e4636cc3f6bcb08e242973e6a0930749c45b82803e49361b7d
7
- data.tar.gz: 9ea24ea8e415140425fe60c9c16e522acea2b3e4c8c5b4514e68ef38f734f51ebda8da9c294f50d4ab021b8e332f34298be468cf15f5de4073063bf2dbe54cfc
6
+ metadata.gz: 8c85a8fbcd7ccf4cc19fcf5fcccdd1d2685dab6439975613eee4c2ed585f9a4aa5dadf3ac6a7873c765a047df070d143bba5068cff4070ff8680e01c9835ccad
7
+ data.tar.gz: 8c871fdfe40a82e3cc04d18f40be11329714f31fe14dcb634c09ea781dae5f9ce9562cd73ae8ab89887a7f0e300ca3030b2d00c53f82676f3ca6bd1aff132cf9
@@ -27,6 +27,10 @@ Style/MultilineTernaryOperator:
27
27
  Style/RegexpLiteral:
28
28
  Enabled: false
29
29
 
30
+ # TODO: Figure out how to do this without URI.encode
31
+ Lint/UriEscapeUnescape:
32
+ Enabled: false
33
+
30
34
  # Screens are big, even when they're small
31
35
  Metrics/LineLength:
32
36
  Enabled: false
@@ -44,7 +48,7 @@ Style/ClassAndModuleChildren:
44
48
  Exclude:
45
49
  - '**/*_test.rb'
46
50
  Metrics/MethodLength:
47
- Max: 16
51
+ Max: 18
48
52
  Exclude:
49
53
  - '**/*_test.rb'
50
54
 
@@ -12,6 +12,13 @@ module CloudappExport
12
12
  @options = options
13
13
  end
14
14
 
15
+ def authenticate!
16
+ response = request("items?per_page=1")
17
+ return true if response.status_code == 200
18
+ # TODO: Use custom exception classes
19
+ raise response.body.strip
20
+ end
21
+
15
22
  def request(path)
16
23
  digest_auth = Net::HTTP::DigestAuth.new
17
24
  uri = URI.parse("https://#{host}/v3/#{path}")
@@ -57,8 +64,16 @@ module CloudappExport
57
64
  @http_response.body
58
65
  end
59
66
 
67
+ def status_code
68
+ @http_response.code.to_i
69
+ end
70
+
60
71
  def data
61
72
  JSON.parse(@http_response.body)['data']
62
73
  end
74
+
75
+ def meta
76
+ JSON.parse(@http_response.body)['meta']
77
+ end
63
78
  end
64
79
  end
@@ -10,13 +10,18 @@ module CloudappExport
10
10
  desc :all, "Export all data from your Cloudapp account"
11
11
  option :limit, default: 5, type: :numeric
12
12
  option :dir, default: "#{ENV['HOME']}/Downloads/CloudappExport", type: :string, desc: "Directory to download all files to"
13
- option :cache, type: :boolean, default: true
13
+ option :cache, type: :boolean, default: false
14
14
  def all
15
+ authenticate!
16
+
15
17
  items = CloudappExport::ItemList.new(
16
18
  api,
17
19
  'limit' => options['limit'],
18
- 'cache' => options['cache'],
20
+ 'use_cache' => options['cache'],
21
+ 'cache_key' => "#{username}:#{options['limit']}",
19
22
  )
23
+ say("Account contains #{set_color items.total_count, :bold} items")
24
+ say("", nil, true)
20
25
 
21
26
  exporter = ::CloudappExport::Exporter.new(
22
27
  items,
@@ -29,27 +34,31 @@ module CloudappExport
29
34
  end
30
35
 
31
36
  # rubocop:disable Metrics/AbcSize
32
- # rubocop:disable Layout/TrailingWhitespace
33
37
  desc :stats, "Show stats for CloudApp items"
34
38
  option :dir, default: "#{ENV['HOME']}/Downloads/CloudappExport", type: :string, desc: "Directory where your files were downloaded to"
35
- option :cache, type: :boolean, default: true
39
+ option :cache, type: :boolean, default: false
36
40
  def stats
41
+ authenticate!
42
+
37
43
  items = CloudappExport::ItemList.new(
38
44
  api,
39
- 'cache' => options['cache'],
40
45
  )
41
-
46
+ say("Account contains #{set_color items.total_count, :bold} items")
47
+ say("", nil, true)
48
+
49
+ say("Dir #{options['dir']}")
50
+ say("", nil, true)
51
+
52
+ # TODO: Just count files directly in local folder
42
53
  downloaded_items = items.data.select { |item| File.exist?("#{options['dir']}/#{item.filename}") }
43
54
  downloaded_items_size = downloaded_items.inject(0) { |sum, item| sum + File.size("#{options['dir']}/#{item.filename}") }
44
-
45
- say("Dir #{options['dir']}")
46
- say("Items #{items.count}")
55
+
47
56
  say("Downloaded #{downloaded_items.count}")
48
57
  say(" #{(downloaded_items_size.to_f / 1_000_000).round 2} mb")
49
58
  end
50
59
  # rubocop:enable Metrics/AbcSize
51
- # rubocop:enable Layout/TrailingWhitespace
52
60
 
61
+ # rubocop:disable Metrics/BlockLength
53
62
  no_commands do
54
63
  def api
55
64
  @api ||= begin
@@ -60,6 +69,14 @@ module CloudappExport
60
69
  end
61
70
  end
62
71
 
72
+ def authenticate!
73
+ api.authenticate!
74
+ say("Successfully authenticated!", :green)
75
+ rescue StandardError => error
76
+ say("Could not authenticate with Cloudapp (#{error.message})", :red)
77
+ Kernel.exit
78
+ end
79
+
63
80
  def username
64
81
  @username ||= begin
65
82
  username = options['username']
@@ -74,10 +91,11 @@ module CloudappExport
74
91
  @password ||= begin
75
92
  password = options['password']
76
93
  password ||= ENV['CLOUDAPP_PASSWORD']
77
- password ||= (ask("Password:", echo: false) && say('*' * 20))
94
+ (password ||= ask("Password:", echo: false)) && say('*' * 20)
78
95
  password || raise("Password is required")
79
96
  end
80
97
  end
81
98
  end
99
+ # rubocop:enable Metrics/BlockLength
82
100
  end
83
101
  end
@@ -25,13 +25,16 @@ module CloudappExport
25
25
  filepath = "#{download_dir}/#{item.filename}"
26
26
  if File.exist?(filepath)
27
27
  log " SK #{item_filesize_human(item)}"
28
+ elsif item['remote_url'].nil? || item['item_type'] == 'pending'
29
+ log " SK No Remote URL"
28
30
  else
29
31
  begin
30
32
  log " DL"
31
33
  copy_file(item['remote_url'], filepath)
32
34
  log " #{item_filesize_human(item)}"
33
35
  rescue StandardError => error
34
- log " ER #{error.message}"
36
+ log " ER #{error.message}\n"
37
+ error.backtrace.each { |line| log " #{line}\n" }
35
38
  end
36
39
  end
37
40
  log "\n"
@@ -44,10 +47,13 @@ module CloudappExport
44
47
  protected
45
48
 
46
49
  def copy_file(remote_url, local_path)
47
- remote_uri = URI(remote_url)
50
+ remote_uri = URI.parse(URI.encode(remote_url, '[]'))
48
51
  File.open(local_path, 'wb') do |file|
49
52
  file << Net::HTTP.get(remote_uri)
50
53
  end
54
+ rescue StandardError => error
55
+ File.delete(local_path)
56
+ raise error
51
57
  end
52
58
 
53
59
  def item_filesize(item)
@@ -1,11 +1,13 @@
1
1
  require "json"
2
+ require "digest"
2
3
 
3
4
  module CloudappExport
4
5
  class ItemList
5
6
  def initialize(api, options = {})
6
7
  @api = api
7
8
  @items = []
8
- @use_cache = !!options['cache']
9
+ @cache_key = options['cache_key']
10
+ @use_cache = options['use_cache']
9
11
  @limit = (options['limit'] || 999_999_999).to_i
10
12
  @offset = (options['offset'] || 0).to_i
11
13
  end
@@ -16,8 +18,12 @@ module CloudappExport
16
18
  end
17
19
 
18
20
  def count
19
- load
20
- [@items.count, @limit].min
21
+ [total_count, @limit].min
22
+ end
23
+
24
+ def total_count
25
+ load_meta
26
+ @meta['count'].to_i
21
27
  end
22
28
 
23
29
  def each(&block)
@@ -42,9 +48,9 @@ module CloudappExport
42
48
  if @use_cache && File.exist?(cache_file_path)
43
49
  items = ::JSON.parse(::File.read(cache_file_path))
44
50
  else
45
- response = @api.request("items?per_page=100000")
51
+ response = @api.request("items?per_page=#{@limit}")
46
52
  items = response.data
47
- ::File.write(cache_file_path, ::JSON.dump(items))
53
+ ::File.write(cache_file_path, ::JSON.dump(items)) if @cache_key
48
54
  end
49
55
  items.map do |attributes|
50
56
  ::CloudappExport::Item.new(attributes)
@@ -52,8 +58,16 @@ module CloudappExport
52
58
  end
53
59
  end
54
60
 
61
+ def load_meta
62
+ @load_meta ||= begin
63
+ response = @api.request("items?per_page=1")
64
+ @meta = response.meta
65
+ end
66
+ end
67
+
55
68
  def cache_file_path
56
- "#{ENV['HOME']}/.cloudapp-export-items.json"
69
+ hashed_cache_key = Digest::MD5.hexdigest(@cache_key)
70
+ "/tmp/cloudapp-export-items-cache-#{hashed_cache_key}.json"
57
71
  end
58
72
  end
59
73
  end
@@ -1,3 +1,3 @@
1
1
  module CloudappExport
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudapp-export
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Qualie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-09 00:00:00.000000000 Z
11
+ date: 2018-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -155,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
155
  version: '0'
156
156
  requirements: []
157
157
  rubyforge_project:
158
- rubygems_version: 2.5.2
158
+ rubygems_version: 2.7.3
159
159
  signing_key:
160
160
  specification_version: 4
161
161
  summary: A quick way to export all the data you have stored in CloudApp