my-local-putio 2.1.0 → 3.0.0

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
2
  SHA256:
3
- metadata.gz: ebd963a16897bd822f3d645dc96c195ed9c2ab6e0d10c7e3105e8f5f1c9a31bb
4
- data.tar.gz: 20504d68d91dee34108c6b3f57253d1a522b25be9c250935459727c5b218ccdb
3
+ metadata.gz: d9926010a7296b64e53e36469ca62e01f01e765b1fc8efdcab2681f45c0bc370
4
+ data.tar.gz: f8235be041d1639f3cc0e5b63fe8ffce9d4755cd1678250d43728763e608c5c6
5
5
  SHA512:
6
- metadata.gz: 320d88bcf89dc9e86ac7f0ce7822148b5599424c5177ac9033cfea2efb2016d2e5740d7e693b968deddb2da68ae18ab5c7497a9b17af407222c37e45e9e1461e
7
- data.tar.gz: 2651b2609fd2943ac205d81eeead93662b28a3b0072873649d2cb95b5afa9b4471a41eb2455710ecf4b8875c621eed05e2e3eaa32d127461c2d27ce5ec27ae53
6
+ metadata.gz: b3325310547f3350073771a381ab300facf64e3a54af83e3494be7078a924eb8975e8f34aedd6f1f7a98bc07145e121ed20eebf26ff4e5d59ac701b2faa8544f
7
+ data.tar.gz: 82debad28c46401a321d8c6d2dadfa56a0b2beda08c905ce5aa7657552977f05eac488c4fe5cbc47e1fb3191b1ac93e0f2db31d907fd4985bd8ae4d5382d5e72
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # v3.0.0
2
+
3
+ - Introducing delete from remote after downloading
4
+ - Breaking changes parameters
5
+ - removed -d option for --debug. Now debug is only available as --debug
6
+ - introduced -d option for --delete-remote
7
+ - More code refactoring
8
+
1
9
  # v2.1.0
2
10
 
3
11
  - Introducing SOCKS5 support with `--socks5-proxy` option.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- my-local-putio (2.1.0)
4
+ my-local-putio (3.0.0)
5
5
  socksify (= 1.7.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -11,10 +11,10 @@ For now the script only supports download the content from your account and keep
11
11
  - Supports SOCKS5 proxy for an even more secure and anonymous transfer, with kill switch, so the application will stop if the proxy became unavailable. No leak connections.
12
12
  - Resume broken/stopped downloads, so you don't have to start from the begin of your huge file.
13
13
  - Simple and easy to run
14
+ - Option to delete the file from put.io after the download
14
15
 
15
16
  #### Planned features:
16
17
 
17
- - Option to delete the file on put.io after sync
18
18
  - Option to download the subtitle if available in put.io list
19
19
 
20
20
  #### Future or ideas: (Feel free to contribute to the list)
@@ -39,12 +39,13 @@ For now the script only supports download the content from your account and keep
39
39
  my-local-putio -h
40
40
 
41
41
  Usage: my-local-putio [options]
42
- -t, --token TOKEN Put.io access token [REQUIRED]
43
- -l, --local-destination PATH Local destination path [REQUIRED]
44
- -v, --version Print my-local-putio version
45
- -s, --silent Hide all messages and progress bar
46
- -d, --debug Debug mode [Developer mode]
47
- --socks5-proxy hostname:port SOCKS5 hostname and port for proxy. Format: 127.0.0.1:1234
42
+ -t, --token TOKEN Put.io access token [REQUIRED]
43
+ -l, --local-destination PATH Local destination path [REQUIRED]
44
+ -d, --delete-remote Delete remote file/folder after the download
45
+ -v, --version Print my-local-putio version
46
+ -s, --silent Hide all messages and progress bar
47
+ --debug Debug mode [Developer mode]
48
+ --socks5-proxy hostname:port SOCKS5 hostname and port for proxy. Format: 127.0.0.1:1234
48
49
 
49
50
  #### Required attributes:
50
51
  * **-t** or **--token**: Your Put.io Token. This attribute becames optional if you set `PUTIO_TOKEN` env variable with your token (Can be inline or into your bash profile). Check examples below.
@@ -63,26 +64,37 @@ With Token variable (inline or exporting):
63
64
  my-local-putio --local-destination Downloads/
64
65
 
65
66
  #### Others attributes:
67
+ * **-d** or **--delete-remote**: Delete the remote file/folder from put.io after downloading
66
68
  * **-h**: Print the help usage message
67
69
  * **-v** or **--version**: Print the version of the application
68
70
  * **-s** or **--silent**: Hide all messages and progress bar
69
- * **-d** or **--debug**: Developer mode: Prints everything and expose URLs with tokens for debug purposes.
71
+ * **--debug**: Developer mode: Prints everything and expose URLs with tokens for debug purposes.
70
72
  * **--socks5-proxy**: Enable the SOCKS5 proxy. If enabled, all the connections for PUT.IO API and the downloads will be performed using this proxy. If the socks connection became unavailable, the application will raise an error and will stop.
71
73
 
72
74
  Examples:
73
75
 
74
76
  my-local-putio -h
75
- my-local-putio -t 123 -l Downloads --silent
77
+ my-local-putio -t 123 -l Downloads --silent -d
76
78
  my-local-putio -t 123 -l Downloads -s
77
79
  my-local-putio --local-destination Downloads -t 123 --debug
78
80
  my-local-putio --local-destination Downloads -t 123 --socks5-proxy 127.0.0.1:3333
79
81
 
80
82
  Verbose output example:
81
83
 
82
- [LOG][2019-07-18 11:11:30] Getting files for Downloads
83
- [LOG][2019-07-18 11:11:31] Getting files for Downloads/ubuntu-18.04.2-desktop-amd64.iso
84
- [LOG][2019-07-18 11:11:31] Downloading: Downloads/ubuntu-18.04.2-desktop-amd64.iso
84
+ my-local-putio -t 123 -l Downloads -d --socks5-proxy 127.0.0.1:3333
85
+
86
+ Starting My Local Put.io - version 3.0.0
87
+ https://github.com/rafaelbiriba/my-local-putio
88
+ =============================================
89
+ Full path of the local destination: /Users/user/Downloads
90
+ >>> Delete remote files enabled!
91
+ >>> SOCKS5 enabled with 127.0.0.1:3333
92
+ =============================================
93
+ [LOG][2019-07-18 11:11:30] Getting file list for /
94
+ [LOG][2019-07-18 11:11:31] Getting file list for /ubuntu
95
+ [LOG][2019-07-18 11:11:31] Downloading: /ubuntu/ubuntu-18.04.2-desktop-amd64.iso
85
96
  ######################################################################## 100.0%
97
+ [LOG][2019-07-18 11:11:33] Deleting remote file: /ubuntu/ubuntu-18.04.2-desktop-amd64.iso
86
98
 
87
99
  #### Troubleshooting
88
100
 
data/bin/my-local-putio CHANGED
@@ -9,6 +9,5 @@ unless open(__FILE__).flock(File::LOCK_EX | File::LOCK_NB)
9
9
  end
10
10
 
11
11
  configuration = MyLocalPutio::Configuration.new
12
- logger = MyLocalPutio::Logger.new(configuration)
13
- putio_cli = MyLocalPutio::PutioCli.new(configuration, logger)
14
- MyLocalPutio::Fetcher.new(configuration, putio_cli, logger).run!
12
+ MyLocalPutio.print_introduction_msg(configuration)
13
+ MyLocalPutio::Fetcher.new(configuration).run!
@@ -26,4 +26,16 @@ require "my-local-putio/putio_cli"
26
26
  require "my-local-putio/fetcher"
27
27
 
28
28
  module MyLocalPutio
29
+ def self.print_introduction_msg(configuration)
30
+ return if configuration.silent
31
+ puts "Starting My Local Put.io - version #{VERSION}"
32
+ puts "https://github.com/rafaelbiriba/my-local-putio"
33
+ puts "============================================="
34
+ puts "Full path of the local destination: #{File.realdirpath(configuration.local_destination)}"
35
+ puts ">>> Delete remote files enabled!" if configuration.delete_remote
36
+ puts ">>> SOCKS5 enabled with #{configuration.socks_host}:#{configuration.socks_port}" if configuration.socks_enabled?
37
+ puts ">>> DEBUG enabled! Hello Mr(s) developer :)" if configuration.debug
38
+ puts "============================================="
39
+ sleep 2 # In case the configurations are not correct, 2 seconds to kill the command line before run
40
+ end
29
41
  end
@@ -1,6 +1,6 @@
1
1
  module MyLocalPutio
2
2
  class Configuration
3
- attr_reader :token, :local_destination, :silent, :debug, :socks_host, :socks_port
3
+ attr_reader :token, :local_destination, :silent, :debug, :socks_host, :socks_port, :delete_remote
4
4
  def initialize
5
5
  read_args_from_envs!
6
6
  parse_args!
@@ -11,18 +11,23 @@ module MyLocalPutio
11
11
  @socks_host || @socks_port
12
12
  end
13
13
 
14
+ def logger
15
+ @logger ||= Logger.new(self)
16
+ end
17
+
14
18
  private
15
19
  def parse_args!
16
20
  OptionParser.new do |opt|
17
21
  opt.on("-t", "--token TOKEN", "Put.io access token [REQUIRED]") { |v| @token = v }
18
22
  opt.on("-l", "--local-destination PATH", "Local destination path [REQUIRED]") { |v| @local_destination = v }
23
+ opt.on("-d", "--delete-remote", "Delete remote file/folder after the download") { |v| @delete_remote = true }
19
24
  opt.on("-v", "--version", "Print my-local-putio version") do
20
25
  puts MyLocalPutio::VERSION
21
26
  exit
22
27
  end
23
28
 
24
29
  opt.on("-s", "--silent", "Hide all messages and progress bar") { |v| @silent = true }
25
- opt.on("-d", "--debug", "Debug mode [Developer mode]") { |v| @debug = true }
30
+ opt.on("--debug", "Debug mode [Developer mode]") { |v| @debug = true }
26
31
  opt.on("--socks5-proxy hostname:port", "SOCKS5 hostname and port for proxy. Format: 127.0.0.1:1234") do |v|
27
32
  @socks_host, @socks_port = v.to_s.split(":")
28
33
  end
@@ -40,10 +45,7 @@ module MyLocalPutio
40
45
  exit
41
46
  end
42
47
 
43
- unless File.writable?(@local_destination)
44
- puts "Cannot write on the local destination path '#{@local_destination}'"
45
- exit
46
- end
48
+ destination_folder_checks!
47
49
 
48
50
  if socks_enabled? && !port_is_open?(@socks_host, @socks_port)
49
51
  puts "Cannot connect to socks using '#{@socks_host}:#{@socks_port}'"
@@ -51,6 +53,14 @@ module MyLocalPutio
51
53
  end
52
54
  end
53
55
 
56
+ def destination_folder_checks!
57
+ return if File.exists?(@local_destination) && File.writable?(@local_destination)
58
+ FileUtils.mkdir_p(@local_destination)
59
+ rescue Errno::EACCES
60
+ puts "Cannot write on the local destination path '#{@local_destination}'"
61
+ exit
62
+ end
63
+
54
64
  def read_args_from_envs!
55
65
  @token ||= ENV["PUTIO_TOKEN"]
56
66
  end
@@ -2,8 +2,10 @@ module MyLocalPutio
2
2
  class Fetcher
3
3
  attr_reader :configuration, :cli, :logger
4
4
 
5
- def initialize(configuration, cli, logger)
6
- @configuration, @cli, @logger = configuration, cli, logger
5
+ def initialize(configuration)
6
+ @configuration = configuration
7
+ @logger = configuration.logger
8
+ @cli = PutioCli.new(@configuration)
7
9
  end
8
10
 
9
11
  def run!
@@ -12,42 +14,59 @@ module MyLocalPutio
12
14
 
13
15
  protected
14
16
 
15
- def fetch_files(id: nil, path: configuration.local_destination)
16
- FileUtils.mkdir_p(path)
17
- logger.log "Getting files for #{path}"
17
+ def fetch_files(id: nil, path: "/")
18
+ logger.log "Getting file list for #{path}"
18
19
  files = cli.get_files(id)["files"]
19
20
 
20
21
  while files.any?
21
- file = OpenStruct.new files.pop
22
- if file.content_type == "application/x-directory"
23
- fetch_files(id: file.id, path: File.join(path, file.name))
24
- else
25
- file_path = File.join(path, file.name)
26
- if File.exists?(file_path) && File.size(file_path) == file.size
27
- logger.log "File already downloaded #{file_path}"
28
- else
29
- url = cli.get_download_url file.id
30
- logger.log "Downloading: #{file_path}"
31
- if ! fetch(url, file_path)
32
- raise "Unable to download #{file_path}"
33
- end
34
- end
35
- end
22
+ file = OpenStruct.new(files.pop)
23
+ process_file(file, path)
36
24
  end
37
25
  end
38
26
 
39
- def fetch(url, path)
27
+ def process_file(file, path)
28
+ local_file_path = File.join(path, file.name)
29
+ if file.content_type == "application/x-directory"
30
+ fetch_files(id: file.id, path: local_file_path)
31
+ else
32
+ download(file, local_file_path) unless file_exists?(local_file_path, file)
33
+ end
34
+ delete_file(local_file_path, file)
35
+ end
36
+
37
+ def delete_file(local_file_path, file)
38
+ logger.log "Deleting remote file: #{local_file_path}"
39
+ cli.delete_file(file.id)
40
+ end
41
+
42
+ def file_exists?(local_file_path, file)
43
+ file_exists = File.exists?(local_file_path) && File.size(local_file_path) == file.size
44
+ logger.log "File already downloaded #{local_file_path}" if file_exists
45
+ file_exists
46
+ end
47
+
48
+ def download_command(url, path)
49
+ destination = File.join(configuration.local_destination, path)
50
+
40
51
  command = [
41
- "curl", "--progress-bar", "-L", "--retry", "5", "-S", "-C", "-", "-o", path, url.to_s
52
+ "curl", "--create-dirs", "--progress-bar", "-L", "--retry", "5", "-S", "-C", "-", "-o", destination, url.to_s
42
53
  ]
43
-
54
+
44
55
  command.push("--silent") if logger.silent?
45
56
 
46
57
  if configuration.socks_enabled?
47
58
  command.push("--socks5-hostname", "#{configuration.socks_host}:#{configuration.socks_port}")
48
59
  end
49
60
 
50
- system(*command)
61
+ return command
62
+ end
63
+
64
+ def download(file, path)
65
+ url = cli.get_download_url(file.id)
66
+ command = download_command(url, path)
67
+ logger.log "Downloading: #{path}"
68
+ fetch_result = system(*command)
69
+ raise "Unable to download #{path}" unless fetch_result
51
70
  end
52
71
  end
53
72
  end
@@ -3,7 +3,7 @@ module MyLocalPutio
3
3
  attr_reader :configuration
4
4
 
5
5
  def initialize(configuration)
6
- @configuration = configuration
6
+ @configuration = configuration
7
7
  end
8
8
 
9
9
  def silent?
@@ -3,11 +3,11 @@ module MyLocalPutio
3
3
  ROOT = "https://api.put.io/v2/"
4
4
  attr_reader :configuration, :endpoint, :http, :logger
5
5
 
6
- def initialize(configuration, endpoint=ROOT, logger)
7
- @configuration, @endpoint, @logger = configuration, URI(endpoint), logger
8
- @http = http_library.new(@endpoint.host, @endpoint.port)
9
- @http.use_ssl = true
10
- @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
6
+ def initialize(configuration)
7
+ @configuration = configuration
8
+ @logger = configuration.logger
9
+ @endpoint = URI(ROOT)
10
+ setup_connection
11
11
  end
12
12
 
13
13
  def get_files(parent_id=nil)
@@ -15,6 +15,17 @@ module MyLocalPutio
15
15
  get("files/list", args)
16
16
  end
17
17
 
18
+ def delete_file(id)
19
+ args = {file_ids: id}
20
+ post("files/delete", args)
21
+ end
22
+
23
+ def delete_file_url
24
+ url = to_url("files/delete")
25
+ url.query = URI.encode_www_form to_args()
26
+ url
27
+ end
28
+
18
29
  def get_download_url(id)
19
30
  url = to_url("files/#{id}/download")
20
31
  url.query = URI.encode_www_form to_args()
@@ -31,6 +42,12 @@ module MyLocalPutio
31
42
  end
32
43
  end
33
44
 
45
+ def setup_connection
46
+ @http = http_library.new(@endpoint.host, @endpoint.port)
47
+ @http.use_ssl = true
48
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
49
+ end
50
+
34
51
  def get(path, args={})
35
52
  url = to_url(path)
36
53
  url.query = URI.encode_www_form to_args(args)
@@ -39,14 +56,14 @@ module MyLocalPutio
39
56
  as_json http.request(req)
40
57
  end
41
58
 
42
- # def post(path, args={})
43
- # url = to_url(path)
44
- # args = to_args(args)
45
- # logger.debug "POST #{url} -- #{args.inspect}"
46
- # req = Net::HTTP::Post.new("/users")
47
- # req.set_form_data(args)
48
- # as_json http.request(req)
49
- # end
59
+ def post(path, args={})
60
+ url = to_url(path)
61
+ args = to_args(args)
62
+ logger.debug "POST #{url} -- #{args.inspect}"
63
+ req = Net::HTTP::Post.new(url)
64
+ req.set_form_data(args)
65
+ as_json http.request(req)
66
+ end
50
67
 
51
68
  def to_url(path)
52
69
  url = endpoint.dup
@@ -1,3 +1,3 @@
1
1
  module MyLocalPutio
2
- VERSION = "2.1.0"
2
+ VERSION = "3.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: my-local-putio
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Biriba
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-19 00:00:00.000000000 Z
11
+ date: 2019-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler