datapimp 1.0.6 → 1.0.8
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 +4 -4
- data/lib/datapimp/cli/sync.rb +12 -10
- data/lib/datapimp/configuration.rb +6 -0
- data/lib/datapimp/core_ext.rb +20 -0
- data/lib/datapimp/logging.rb +15 -0
- data/lib/datapimp/sync/dropbox_folder.rb +24 -12
- data/lib/datapimp/sync/s3_bucket.rb +120 -0
- data/lib/datapimp/version.rb +1 -1
- data/lib/datapimp.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34acb2d1cc3f7c113a962128faa64f3d0ae8d382
|
4
|
+
data.tar.gz: 9b4cf19a026f35bb3c978a7eafef314ccebe2487
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 738b6bd20b2be6ef71a228406dd36b20197427b1afcc6ffe963df23d34c71b36180bcd0e037753e36698238a5209011f0a86afaf64f70e9a068be2248893f29b
|
7
|
+
data.tar.gz: 76e95ba024481ade64e27edf5ebebfcc592c551ed9e62edd40ee2c88be87bc416345090350396befd4cdae01f4b8001cb59775bd43e444b6e48f233a56f27649
|
data/lib/datapimp/cli/sync.rb
CHANGED
@@ -13,16 +13,18 @@ command "sync folder" do |c|
|
|
13
13
|
local, remote = args
|
14
14
|
|
15
15
|
folder = case
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
when options.type == "dropbox"
|
17
|
+
Datapimp::Sync::DropboxFolder.new(local: local, remote: remote)
|
18
|
+
when options.type == "google"
|
19
|
+
# Return the folders
|
20
|
+
# collection = Datapimp::Sync.google.api.collections.first
|
21
|
+
#
|
22
|
+
# svg = collection.files.first
|
23
|
+
# svg.export_as_file(/download/path, "image/svg+xml")
|
24
|
+
Datapimp::Sync::GoogleDriveFolder.new(local: local, remote: remote)
|
25
|
+
when options.type == "aws" || options.type == "s3"
|
26
|
+
Datapimp::Sync::S3Bucket.new(local: local, remote: remote)
|
27
|
+
end
|
26
28
|
|
27
29
|
folder.run(options.action, options.to_hash.to_mash)
|
28
30
|
end
|
data/lib/datapimp/core_ext.rb
CHANGED
@@ -3,3 +3,23 @@ class Hash
|
|
3
3
|
Hashie::Mash.new(self)
|
4
4
|
end
|
5
5
|
end
|
6
|
+
|
7
|
+
class Pathname
|
8
|
+
def to_pathname
|
9
|
+
self
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class String
|
14
|
+
def to_pathname
|
15
|
+
Pathname(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def without_leading_slash
|
19
|
+
gsub(/^\//,'')
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_leading_slash
|
23
|
+
"/#{without_leading_slash}"
|
24
|
+
end
|
25
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Datapimp
|
2
2
|
class Sync::DropboxFolder < Hashie::Mash
|
3
|
+
include Datapimp::Logging
|
4
|
+
|
3
5
|
# Provides easy access to the Dropbox client
|
4
6
|
def dropbox
|
5
7
|
@dropbox ||= Datapimp::Sync.dropbox
|
@@ -48,23 +50,33 @@ module Datapimp
|
|
48
50
|
def run(action, options={})
|
49
51
|
action = action.to_sym
|
50
52
|
|
51
|
-
|
52
|
-
if remote_path_missing?
|
53
|
-
dropbox.mkdir(remote)
|
54
|
-
end
|
55
|
-
|
56
|
-
Dir[local_path.join("**/*")].each do |f|
|
57
|
-
# Upload the file
|
58
|
-
binding.pry
|
59
|
-
end
|
53
|
+
log "DropboxFolder run:#{action}"
|
60
54
|
|
55
|
+
if action == :push
|
56
|
+
run_push_action
|
61
57
|
elsif action == :pull
|
62
|
-
|
63
|
-
# Implement the Delta call
|
58
|
+
run_pull_action
|
64
59
|
end
|
65
60
|
end
|
66
61
|
|
67
|
-
def
|
62
|
+
def run_pull_action
|
63
|
+
binding.pry
|
64
|
+
end
|
65
|
+
|
66
|
+
def run_push_action
|
67
|
+
if remote_path_missing?
|
68
|
+
dropbox.mkdir(remote)
|
69
|
+
end
|
70
|
+
|
71
|
+
Dir[local_path.join("**/*")].each do |f|
|
72
|
+
f = Pathname(f)
|
73
|
+
base = f.relative_path_from(local_path).to_s
|
74
|
+
target_path = File.join(remote, base)
|
75
|
+
|
76
|
+
log "Uploading #{ f } to #{target_path}"
|
77
|
+
|
78
|
+
dropbox.upload(target_path, f.read, :overwrite => false)
|
79
|
+
end
|
68
80
|
end
|
69
81
|
end
|
70
82
|
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Datapimp
|
2
|
+
module Sync
|
3
|
+
class S3Bucket < Hashie::Mash
|
4
|
+
include Datapimp::Logging
|
5
|
+
|
6
|
+
# returns the s3 bucket via fog
|
7
|
+
def s3
|
8
|
+
@s3 ||= Datapimp::Sync.amazon.storage.directories.get(remote)
|
9
|
+
end
|
10
|
+
|
11
|
+
def local_path
|
12
|
+
Pathname(local)
|
13
|
+
end
|
14
|
+
|
15
|
+
def deploy_manifest_path
|
16
|
+
Datapimp.config.deploy_manifests_path
|
17
|
+
.tap {|p| FileUtils.mkdir_p(p) }
|
18
|
+
.join(remote.to_s.parameterize + '.json')
|
19
|
+
end
|
20
|
+
|
21
|
+
def deploy_manifest
|
22
|
+
@deploy_manifest ||= (JSON.parse(deploy_manifest_path.read) || {} rescue {})
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_deploy_manifest_from_remote
|
26
|
+
# TODO
|
27
|
+
# Implement
|
28
|
+
end
|
29
|
+
|
30
|
+
# builds a manifest of MD5 hashes for each file
|
31
|
+
# so that we aren't deploying stuff which is the
|
32
|
+
# same since last time we deployed
|
33
|
+
def prepare_manifest_for(entries)
|
34
|
+
m = deploy_manifest
|
35
|
+
|
36
|
+
entries.each do |entry|
|
37
|
+
destination = Pathname(entry).relative_path_from(local_path).to_s.without_leading_slash
|
38
|
+
|
39
|
+
deploy_manifest.fetch(destination) do
|
40
|
+
next unless destination.match(/\w+\.\w+/)
|
41
|
+
m[destination] = nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def run_update_acl_action(options={})
|
47
|
+
s3.files.each do |file|
|
48
|
+
file.acl = 'public-read'
|
49
|
+
file.save
|
50
|
+
log "Updated acl for #{ file.key } to public-read"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def asset_fingerprints
|
55
|
+
deploy_manifest['asset_fingerprints'] ||= {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_push_action(options={})
|
59
|
+
entries = Dir[local_path.join('**/*')].map(&:to_pathname)
|
60
|
+
prepare_manifest_for(entries)
|
61
|
+
|
62
|
+
entries.reject! { |entry| entry.to_s.match(/\.DS_Store/) }
|
63
|
+
entries.reject!(&:directory?)
|
64
|
+
|
65
|
+
uploaded = deploy_manifest['uploaded'] = []
|
66
|
+
|
67
|
+
entries.each do |entry|
|
68
|
+
destination = entry.relative_path_from(local_path).to_s.without_leading_slash
|
69
|
+
fingerprint = Digest::MD5.hexdigest(entry.read)
|
70
|
+
|
71
|
+
if asset_fingerprints[destination] == fingerprint
|
72
|
+
#log "Skipping #{ destination }: found in manifest"
|
73
|
+
next
|
74
|
+
end
|
75
|
+
|
76
|
+
if existing = s3.files.get(destination)
|
77
|
+
if existing.etag == fingerprint
|
78
|
+
log "Skipping #{ destination }: similar etag"
|
79
|
+
else
|
80
|
+
existing.body = entry.read
|
81
|
+
existing.acl = 'public-read'
|
82
|
+
log "Updated #{ destination }"
|
83
|
+
uploaded << destination
|
84
|
+
existing.save
|
85
|
+
end
|
86
|
+
else
|
87
|
+
log "Uploaded #{ destination }"
|
88
|
+
s3.files.create(key: destination, body: entry.read, acl: 'public-read')
|
89
|
+
uploaded << destination
|
90
|
+
end
|
91
|
+
|
92
|
+
asset_fingerprints[destination] = fingerprint
|
93
|
+
end
|
94
|
+
|
95
|
+
if count == 0
|
96
|
+
return
|
97
|
+
end
|
98
|
+
|
99
|
+
log "Saving deploy manifest. #{ deploy_manifest.keys.length } entries"
|
100
|
+
deploy_manifest_path.open("w+") {|fh| fh.write(deploy_manifest.to_json) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def run_pull_action(options={})
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
def run(action, options={})
|
108
|
+
action = action.to_sym
|
109
|
+
|
110
|
+
if action == :push
|
111
|
+
run_push_action(options)
|
112
|
+
elsif action == :update_acl
|
113
|
+
run_update_acl_action(options={})
|
114
|
+
elsif action == :pull
|
115
|
+
run_pull_action
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/lib/datapimp/version.rb
CHANGED
data/lib/datapimp.rb
CHANGED
@@ -30,7 +30,9 @@ end
|
|
30
30
|
|
31
31
|
require 'datapimp/version'
|
32
32
|
require 'datapimp/configuration'
|
33
|
+
require 'datapimp/logging'
|
33
34
|
require 'datapimp/sources'
|
34
35
|
require 'datapimp/sync'
|
35
36
|
require 'datapimp/sync/dropbox_folder'
|
36
37
|
require 'datapimp/sync/google_drive_folder'
|
38
|
+
require 'datapimp/sync/s3_bucket'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datapimp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Soeder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -380,6 +380,7 @@ files:
|
|
380
380
|
- lib/datapimp/clients/google.rb
|
381
381
|
- lib/datapimp/configuration.rb
|
382
382
|
- lib/datapimp/core_ext.rb
|
383
|
+
- lib/datapimp/logging.rb
|
383
384
|
- lib/datapimp/sources.rb
|
384
385
|
- lib/datapimp/sources/dropbox.rb
|
385
386
|
- lib/datapimp/sources/excel.rb
|
@@ -391,6 +392,7 @@ files:
|
|
391
392
|
- lib/datapimp/sync/dropbox_delta.rb
|
392
393
|
- lib/datapimp/sync/dropbox_folder.rb
|
393
394
|
- lib/datapimp/sync/google_drive_folder.rb
|
395
|
+
- lib/datapimp/sync/s3_bucket.rb
|
394
396
|
- lib/datapimp/version.rb
|
395
397
|
- packaging/wrapper.sh
|
396
398
|
- spec/spec_helper.rb
|