-
Notifications
You must be signed in to change notification settings - Fork 1
/
putio-sync.rb
128 lines (109 loc) · 2.73 KB
/
putio-sync.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
require 'cgi'
require 'fileutils'
require 'net/http'
require 'openssl'
require 'ostruct'
require 'pp'
require 'uri'
require 'yaml'
unless open(__FILE__).flock(File::LOCK_EX | File::LOCK_NB)
puts "script already running..."
exit
end
# https://api.put.io/v2/docs/
class PutIO
ROOT = "https://api.put.io/v2/"
attr_reader :token, :endpoint, :http
def initialize(token, endpoint=ROOT)
@token, @endpoint = token, URI(endpoint)
@http = Net::HTTP.new(@endpoint.host, @endpoint.port)
@http.use_ssl = true
# Not good ...
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
def get_files(parent_id=nil)
args = parent_id ? {parent_id: parent_id} : {}
get('files/list', args)
end
def get_download_url(id)
# Follow redirect plz
url = to_url("files/#{id}/download")
url.query = URI.encode_www_form to_args()
url
end
protected
def get(path, args={})
url = to_url(path)
url.query = URI.encode_www_form to_args(args)
req = Net::HTTP::Get.new(url.request_uri)
puts "GET #{url}"
as_json http.request(req)
end
def post(path, args={})
url = to_url(path)
args = to_args(args)
puts "POST #{url} -- #{args.inspect}"
req = Net::HTTP::Post.new("/users")
req.set_form_data(args)
as_json http.request(req)
end
def to_url(path)
url = endpoint.dup
url.path += path
url
end
def to_args(args={})
ret = {}
args.each_pair do |k,v|
ret[k.to_s] = v
end
args['oauth_token'] = @token
args
end
def as_json(res)
raise "woot? #{res.inspect}" unless res.is_a?(Net::HTTPSuccess)
YAML.load res.body
end
end
class Fetcher
attr_reader :root, :cli
def initialize(root, cli)
@root, @cli = root, cli
end
def run!
fetch_files()
end
protected
def fetch_files(id=nil, path=@root)
FileUtils.mkdir_p(path)
puts "*** Getting files for #{path}"
files = cli.get_files(id)['files']
while files.any?
file = OpenStruct.new files.pop
if file.content_type == "application/x-directory"
fetch_files file.id, File.join(path, file.name)
else
file_path = File.join(path, file.name)
if File.exists?(file_path) && File.size(file_path) == file.size
puts "*** File already downloaded #{file.name}"
else
url = cli.get_download_url file.id
if ! fetch(url, file_path)
raise "Unable to download #{file.name}"
end
end
end
end
end
def fetch(url, path)
command = [
'curl', '-L', '--retry', '5', '-S', '-C', '-', '-o', path, url.to_s
]
p command
system(*command)
end
end
root = ARGV[0] || File.expand_path('../putio', __FILE__)
token = ARGV[1] || ENV['PUTIO_TOKEN']
x = PutIO.new(token)
Fetcher.new(root, x).run!