cloudapp-export 0.2.1 → 0.2.2

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
- 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