my-local-putio 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +20 -0
- data/README.md +97 -0
- data/Rakefile +2 -0
- data/bin/my-local-putio +14 -0
- data/lib/my-local-putio/configuration.rb +34 -0
- data/lib/my-local-putio/fetcher.rb +47 -0
- data/lib/my-local-putio/logger.rb +33 -0
- data/lib/my-local-putio/putio_cli.rb +69 -0
- data/lib/my-local-putio/version.rb +3 -0
- data/lib/my-local-putio.rb +27 -0
- data/my-local-putio.gemspec +29 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 61a79c61fc4ee64058c994640793d2ca8648f6810f3191096f7075b9eae43ae9
|
4
|
+
data.tar.gz: ff63d69b128c8d017fcdeffa0e345dd775b5fa6d6e14ff3f6526204b127e2630
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 15a91d0b583c45f9997ac9f19c412efc1bf2fad3b63dd6c801f9e86f995ae76dc95a7fc3f6ccde501b9c683f0d529af1c59e3e17131edcb9345f872eeeb0021a
|
7
|
+
data.tar.gz: b84abe3a51341f71ea02658221589d7d78384a003a28d32ff55e258a57c9c04cb4c133d7c30a6ca09b0bafbd02e7cd0a06d6da3eca3d30adfab1311281f2cd95
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/*
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.3
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
my-local-putio (1.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
rake (10.5.0)
|
10
|
+
|
11
|
+
PLATFORMS
|
12
|
+
ruby
|
13
|
+
|
14
|
+
DEPENDENCIES
|
15
|
+
bundler (~> 2.0)
|
16
|
+
my-local-putio!
|
17
|
+
rake (~> 10.0)
|
18
|
+
|
19
|
+
BUNDLED WITH
|
20
|
+
2.0.2
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
My Local Put.io
|
2
|
+
===========
|
3
|
+
|
4
|
+
The easiest script to synchronize all your [Put.io](http://put.io) files locally.
|
5
|
+
|
6
|
+
For now the script only supports download the content from your account and keep it locally.
|
7
|
+
|
8
|
+
### Features
|
9
|
+
|
10
|
+
- Check and skip already downloaded files
|
11
|
+
- Resume broken/stopped downloads, so you don't have to start from the begin of your huge file.
|
12
|
+
- Simple and easy to run
|
13
|
+
|
14
|
+
#### Planned features:
|
15
|
+
|
16
|
+
- Option to delete the file on put.io after sync
|
17
|
+
- Option to download the subtitle if available in put.io list
|
18
|
+
|
19
|
+
#### Future or ideas: (Feel free to contribute to the list)
|
20
|
+
|
21
|
+
- Add a magnet/torrent to the put.io account based on local files or references.
|
22
|
+
|
23
|
+
## Copyright Disclaimer
|
24
|
+
|
25
|
+
`My Local Put.io` uses the official Put.io API v2. Use this tool for legal purposes only. You are the only one responsible for what you are downloading from your put.io account, ensuring that your download does not infringe any legal or copyright constraints.
|
26
|
+
`My Local Put.io` or the script author will not take responsibility for any of your downloading acts.
|
27
|
+
|
28
|
+
## Install
|
29
|
+
|
30
|
+
* Install ruby 2.6.0+
|
31
|
+
* Generate a token for your put.io account: https://app.put.io/authenticate?client_id=1&response_type=oob
|
32
|
+
* Install the `my-local-putio` gem:
|
33
|
+
|
34
|
+
gem install my-local-putio
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
my-local-putio -h
|
39
|
+
|
40
|
+
Usage: my-local-putio [options]
|
41
|
+
-t, --token TOKEN Put.io access token [REQUIRED]
|
42
|
+
-d, --destination DESTINATION Destination path [REQUIRED]
|
43
|
+
-v, --verbose Show messages and progress bar
|
44
|
+
--debug Debug mode [Developer mode]
|
45
|
+
|
46
|
+
#### Required attributes:
|
47
|
+
* **-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.
|
48
|
+
* **-d** or **--destination**: Local destination folder
|
49
|
+
|
50
|
+
Examples:
|
51
|
+
|
52
|
+
my-local-putio -t 123 -d Downloads
|
53
|
+
my-local-putio -d Downloads --token 123
|
54
|
+
|
55
|
+
With Token variable (inline or exporting):
|
56
|
+
|
57
|
+
PUTIO_TOKEN=123 my-local-putio -d Downloads
|
58
|
+
|
59
|
+
export PUTIO_TOKEN=123
|
60
|
+
my-local-putio -d Downloads
|
61
|
+
|
62
|
+
#### Others attributes:
|
63
|
+
* **-h**: Print the help usage message
|
64
|
+
* **-v** or **--verbose**: Show useful information about your downloads
|
65
|
+
* **--debug**: Developer mode: Prints everything (also verbose messages) and expose URLs with tokens for debug purposes.
|
66
|
+
|
67
|
+
Examples:
|
68
|
+
|
69
|
+
my-local-putio -h
|
70
|
+
my-local-putio -t 123 -d Downloads --verbose
|
71
|
+
my-local-putio -t 123 -d Downloads -v
|
72
|
+
my-local-putio --destination Downloads -t 123 --debug
|
73
|
+
|
74
|
+
Verbose output example:
|
75
|
+
|
76
|
+
[LOG][2019-07-18 11:11:30] Getting files for Downloads
|
77
|
+
[LOG][2019-07-18 11:11:31] Getting files for Downloads/ubuntu-18.04.2-desktop-amd64.iso
|
78
|
+
[LOG][2019-07-18 11:11:31] Downloading: Downloads/ubuntu-18.04.2-desktop-amd64.iso
|
79
|
+
######################################################################## 100.0%
|
80
|
+
|
81
|
+
#### Troubleshooting
|
82
|
+
|
83
|
+
##### 401 UNAUTHORIZED
|
84
|
+
If you token is invalid, the script will stop with `401` error message.
|
85
|
+
|
86
|
+
|
87
|
+
## Contributing
|
88
|
+
|
89
|
+
First of all, **thank you** for wanting to help!
|
90
|
+
|
91
|
+
1. [Fork it](https://help.github.com/articles/fork-a-repo).
|
92
|
+
2. Create a feature branch - `git checkout -b more_magic`
|
93
|
+
3. Add tests and make your changes
|
94
|
+
4. Check if tests are ok - `rake spec`
|
95
|
+
5. Commit changes - `git commit -am "Added more magic"`
|
96
|
+
6. Push to Github - `git push origin more_magic`
|
97
|
+
7. Send a [pull request](https://help.github.com/articles/using-pull-requests)! :heart:
|
data/Rakefile
ADDED
data/bin/my-local-putio
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "my-local-putio"
|
5
|
+
|
6
|
+
unless open(__FILE__).flock(File::LOCK_EX | File::LOCK_NB)
|
7
|
+
puts "Script already running..."
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
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!
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module MyLocalPutio
|
2
|
+
class Configuration
|
3
|
+
attr_reader :token, :destination, :verbose, :debug
|
4
|
+
def initialize
|
5
|
+
read_args_from_envs!
|
6
|
+
parse_args!
|
7
|
+
validate_args!
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def parse_args!
|
12
|
+
OptionParser.new do |opt|
|
13
|
+
opt.on("-t", "--token TOKEN", "Put.io access token [REQUIRED]") { |v| @token = v }
|
14
|
+
opt.on("-d", "--destination DESTINATION", "Destination path [REQUIRED]") { |v| @destination = v }
|
15
|
+
opt.on("-v", "--verbose", "Show messages and progress bar") { |v| @verbose = true }
|
16
|
+
opt.on("--debug", "Debug mode [Developer mode]") { |v| @debug = true }
|
17
|
+
end.parse!
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_args!
|
21
|
+
unless @token
|
22
|
+
raise OptionParser::MissingArgument.new("--token")
|
23
|
+
end
|
24
|
+
|
25
|
+
unless @destination
|
26
|
+
raise OptionParser::MissingArgument.new("--destination")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def read_args_from_envs!
|
31
|
+
@token ||= ENV["PUTIO_TOKEN"]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module MyLocalPutio
|
2
|
+
class Fetcher
|
3
|
+
attr_reader :configuration, :cli, :logger
|
4
|
+
|
5
|
+
def initialize(configuration, cli, logger)
|
6
|
+
@configuration, @cli, @logger = configuration, cli, logger
|
7
|
+
end
|
8
|
+
|
9
|
+
def run!
|
10
|
+
fetch_files
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def fetch_files(id: nil, path: configuration.destination)
|
16
|
+
FileUtils.mkdir_p(path)
|
17
|
+
logger.log "Getting files for #{path}"
|
18
|
+
files = cli.get_files(id)["files"]
|
19
|
+
|
20
|
+
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
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch(url, path)
|
40
|
+
command = [
|
41
|
+
"curl", "--progress-bar", "-L", "--retry", "5", "-S", "-C", "-", "-o", path, url.to_s
|
42
|
+
]
|
43
|
+
command.push("--silent") unless logger.verbose?
|
44
|
+
system(*command)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MyLocalPutio
|
2
|
+
class Logger
|
3
|
+
attr_reader :configuration
|
4
|
+
|
5
|
+
def initialize(configuration)
|
6
|
+
@configuration = configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
def verbose?
|
10
|
+
configuration.verbose
|
11
|
+
end
|
12
|
+
|
13
|
+
def debug?
|
14
|
+
configuration.debug
|
15
|
+
end
|
16
|
+
|
17
|
+
def debug(msg)
|
18
|
+
return unless debug?
|
19
|
+
puts "[DEBUG][#{time_now}] #{msg}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def log(msg)
|
23
|
+
return unless verbose? || debug?
|
24
|
+
puts "[LOG][#{time_now}] #{msg}"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def time_now
|
30
|
+
Time.now.strftime("%F %H:%M:%S")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module MyLocalPutio
|
2
|
+
class PutioCli
|
3
|
+
ROOT = "https://api.put.io/v2/"
|
4
|
+
attr_reader :configuration, :endpoint, :http, :logger
|
5
|
+
|
6
|
+
def initialize(configuration, endpoint=ROOT, logger)
|
7
|
+
@configuration, @endpoint, @logger = configuration, URI(endpoint), logger
|
8
|
+
@http = Net::HTTP.new(@endpoint.host, @endpoint.port)
|
9
|
+
@http.use_ssl = true
|
10
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_files(parent_id=nil)
|
14
|
+
args = parent_id ? {parent_id: parent_id} : {}
|
15
|
+
get("files/list", args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_download_url(id)
|
19
|
+
# Follow redirect plz
|
20
|
+
url = to_url("files/#{id}/download")
|
21
|
+
url.query = URI.encode_www_form to_args()
|
22
|
+
url
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def log(msg)
|
28
|
+
return unless configuration.verbose
|
29
|
+
puts msg
|
30
|
+
end
|
31
|
+
|
32
|
+
def get(path, args={})
|
33
|
+
url = to_url(path)
|
34
|
+
url.query = URI.encode_www_form to_args(args)
|
35
|
+
req = Net::HTTP::Get.new(url.request_uri)
|
36
|
+
logger.debug "GET #{url}"
|
37
|
+
as_json http.request(req)
|
38
|
+
end
|
39
|
+
|
40
|
+
# def post(path, args={})
|
41
|
+
# url = to_url(path)
|
42
|
+
# args = to_args(args)
|
43
|
+
# logger.debug "POST #{url} -- #{args.inspect}"
|
44
|
+
# req = Net::HTTP::Post.new("/users")
|
45
|
+
# req.set_form_data(args)
|
46
|
+
# as_json http.request(req)
|
47
|
+
# end
|
48
|
+
|
49
|
+
def to_url(path)
|
50
|
+
url = endpoint.dup
|
51
|
+
url.path += path
|
52
|
+
url
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_args(args={})
|
56
|
+
ret = {}
|
57
|
+
args.each_pair do |k,v|
|
58
|
+
ret[k.to_s] = v
|
59
|
+
end
|
60
|
+
args["oauth_token"] = configuration.token
|
61
|
+
args
|
62
|
+
end
|
63
|
+
|
64
|
+
def as_json(res)
|
65
|
+
raise "woot? #{res.inspect}" unless res.is_a?(Net::HTTPSuccess)
|
66
|
+
YAML.load res.body
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Put.io Fetcher
|
2
|
+
#
|
3
|
+
# Put.io download script! The easiest way to have all all your put.io files locally.
|
4
|
+
#
|
5
|
+
# Created by: Rafael Biriba - biribarj@gmail.com
|
6
|
+
# More info: https://github.com/rafaelbiriba/putio-fetcher
|
7
|
+
#
|
8
|
+
# Copyright disclaimer:
|
9
|
+
# Put.io fetcher uses the official Put.io API v2. Use this tool for legal purposes
|
10
|
+
# only. You are the only one responsible for what you are downloading from
|
11
|
+
# your put.io account, ensuring that your download does not infringe any legal
|
12
|
+
# or copyright constraints. Put.io Fetcher or the script author will not take
|
13
|
+
# responsibility for any of your downloading acts.
|
14
|
+
|
15
|
+
require "net/http"
|
16
|
+
require "openssl"
|
17
|
+
require "ostruct"
|
18
|
+
require "yaml"
|
19
|
+
require "optparse"
|
20
|
+
require "putio_fetcher/version"
|
21
|
+
require "putio_fetcher/configuration"
|
22
|
+
require "putio_fetcher/logger"
|
23
|
+
require "putio_fetcher/putio_cli"
|
24
|
+
require "putio_fetcher/fetcher"
|
25
|
+
|
26
|
+
module MyLocalPutio
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "my-local-putio/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "my-local-putio"
|
7
|
+
spec.version = MyLocalPutio::VERSION
|
8
|
+
spec.authors = ["Rafael Biriba"]
|
9
|
+
spec.email = ["biribarj@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "The easiest script to synchronise all your put.io files locally."
|
12
|
+
spec.description = "The easiest script to synchronise all your put.io files locally."
|
13
|
+
spec.homepage = "https://github.com/rafaelbiriba/my-local-putio"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = "https://github.com/rafaelbiriba/my-local-putio"
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/rafaelbiriba/my-local-putio/blob/master/CHANGELOG.md"
|
19
|
+
|
20
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
21
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
end
|
23
|
+
spec.bindir = "bin"
|
24
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
25
|
+
spec.require_paths = ["lib"]
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: my-local-putio
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rafael Biriba
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: The easiest script to synchronise all your put.io files locally.
|
42
|
+
email:
|
43
|
+
- biribarj@gmail.com
|
44
|
+
executables:
|
45
|
+
- my-local-putio
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- ".ruby-version"
|
51
|
+
- CHANGELOG.md
|
52
|
+
- Gemfile
|
53
|
+
- Gemfile.lock
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- bin/my-local-putio
|
57
|
+
- lib/my-local-putio.rb
|
58
|
+
- lib/my-local-putio/configuration.rb
|
59
|
+
- lib/my-local-putio/fetcher.rb
|
60
|
+
- lib/my-local-putio/logger.rb
|
61
|
+
- lib/my-local-putio/putio_cli.rb
|
62
|
+
- lib/my-local-putio/version.rb
|
63
|
+
- my-local-putio.gemspec
|
64
|
+
homepage: https://github.com/rafaelbiriba/my-local-putio
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata:
|
68
|
+
homepage_uri: https://github.com/rafaelbiriba/my-local-putio
|
69
|
+
source_code_uri: https://github.com/rafaelbiriba/my-local-putio
|
70
|
+
changelog_uri: https://github.com/rafaelbiriba/my-local-putio/blob/master/CHANGELOG.md
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubygems_version: 3.0.3
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: The easiest script to synchronise all your put.io files locally.
|
90
|
+
test_files: []
|