soundcloud-downloader 1.0.0
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 +7 -0
- data/lib/soundcloud-downloader.rb +140 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ed8162aa8a8d65712a20c284d6409dc635265b70
|
4
|
+
data.tar.gz: 4f338da02c20eba36c6d3fc2628e6a423880e9ad
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c94e057b0572babeee47ae7574d8b86d71b9e87cbb558c90ad3915e5d24e7891f8a8d04541e2bea177dee0ba1ab046d9146bed5e837ada14987f5a78abf70be6
|
7
|
+
data.tar.gz: 6b002c8f1f6a5b160d6077a3efa396e1c154ba12f775a5f84a12c72c6bda3f7feb17a04c98a7b30711323e9ea5ccdaa051ffefd6ab77b997bcec8fc4827b1132
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
# Public: Basic SoundCloud Stream Client, allows to get the url of a sound from it's API url
|
7
|
+
# and download the sound even if private by following the redirection.
|
8
|
+
#
|
9
|
+
# Classes:
|
10
|
+
#
|
11
|
+
# SoundCloud::Downloader::Helpers <-- Display helpers
|
12
|
+
# SoundCloud::Downloader::Client <-- Download Client
|
13
|
+
#
|
14
|
+
module SoundCloud
|
15
|
+
module Downloader
|
16
|
+
class Error < StandardError; end
|
17
|
+
|
18
|
+
class Helpers
|
19
|
+
# Public: Displays a progress bar
|
20
|
+
#
|
21
|
+
# char - A unique Character, respresenting the progress in the progress bar.
|
22
|
+
# end_char - A unique Character, showed on the end of the progress bar.
|
23
|
+
# position - A Number, the current position.
|
24
|
+
#
|
25
|
+
# Examples:
|
26
|
+
#
|
27
|
+
# SoundCloud::Downloader::Helpers.progress_bar('=', '>', 5)
|
28
|
+
# # =====>
|
29
|
+
# SoundCloud::Downloader::Helpers.progress_bar('=', '>', 10)
|
30
|
+
# # ==========>
|
31
|
+
#
|
32
|
+
def self.progress_bar(char, end_char, position)
|
33
|
+
print "\r\e[0K" + (char * position) + end_char
|
34
|
+
$stdout.flush
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Client
|
39
|
+
|
40
|
+
attr_reader :client_id, :path, :fs_location, :url
|
41
|
+
|
42
|
+
# Public: Constructor
|
43
|
+
#
|
44
|
+
# opts - A Hash of options
|
45
|
+
# :client_id - The soundcloud client id as a String.
|
46
|
+
# :path - A String, path to a directory where downloaded files will be stored. If no path is specified, downloaded files will be saved in a temporary directory and deleted upon exit
|
47
|
+
#
|
48
|
+
# Returns an instance of StreamClient
|
49
|
+
def initialize(opts)
|
50
|
+
@client_id = opts[:client_id]
|
51
|
+
@path = opts[:path]
|
52
|
+
@url = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
# Public: resolves a soundcloud API url
|
56
|
+
#
|
57
|
+
# url - The URL to resolve as a String.
|
58
|
+
#
|
59
|
+
# Returns the direct URL to the corresponding mp3 file as a String.
|
60
|
+
def resolve url
|
61
|
+
uri = URI.parse(url)
|
62
|
+
res = Net::HTTP.start('api.soundcloud.com', 443, use_ssl: true) do |http|
|
63
|
+
http.request(Net::HTTP::Get.new("#{uri.path}?client_id=#{@client_id}"))
|
64
|
+
end
|
65
|
+
|
66
|
+
if res.code == '302'
|
67
|
+
@url = res.header['Location']
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Public: loads a file, either downloading it in the specified directory or in a temporory file
|
72
|
+
#
|
73
|
+
# name - A String, the downloaded mp3 file name. If none specified, a random name will be given. If a file already exists, it will not be reloaded.
|
74
|
+
# block - A Proc, Lambda, Block, called with the following arguments : content_size, progress, content
|
75
|
+
#
|
76
|
+
# Returns the location of the downloaded file as a String.
|
77
|
+
def load(name = SecureRandom.hex, &block)
|
78
|
+
unless @url
|
79
|
+
raise SoundCloud::Downloader::Error.new('URL not found, did you call `#resolve` first ?')
|
80
|
+
end
|
81
|
+
|
82
|
+
uri = URI.parse(@url)
|
83
|
+
file_path = fs_location(name)
|
84
|
+
|
85
|
+
unless File.exists?(file_path)
|
86
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
87
|
+
request = Net::HTTP::Get.new(@url)
|
88
|
+
|
89
|
+
http.request request do |response|
|
90
|
+
open fs_location(name), 'w' do |io|
|
91
|
+
|
92
|
+
position = 0
|
93
|
+
length = response['Content-Length'].to_i
|
94
|
+
|
95
|
+
response.read_body do |chunk|
|
96
|
+
if block_given?
|
97
|
+
position += chunk.length
|
98
|
+
block.call(length.fdiv(length) * 100, (position.fdiv(length) * 100).to_i, chunk)
|
99
|
+
end
|
100
|
+
io.write chunk
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
@fs_location
|
108
|
+
end
|
109
|
+
|
110
|
+
# Public: deletes the last loaded file
|
111
|
+
#
|
112
|
+
# force - A Boolean Flag, if set to :force, or true, it will also delete the file in your `path` directory.
|
113
|
+
#
|
114
|
+
# Returns Nothing.
|
115
|
+
def end_stream(force = false)
|
116
|
+
raise SoundCloud::Downloader::Error.new('No files were loaded, nothing to clean up.') unless @fs_location
|
117
|
+
if (force && @path) || (!@path)
|
118
|
+
FileUtils.rm(@fs_location)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
# Private: determines the location of the downloaded file on the file system
|
125
|
+
#
|
126
|
+
# name - the name of the file as a String
|
127
|
+
#
|
128
|
+
# Returns the path as a String.
|
129
|
+
def fs_location(name)
|
130
|
+
@fs_location =
|
131
|
+
if @path
|
132
|
+
FileUtils.mkdir(@path) unless File.directory?(@path)
|
133
|
+
"#@path/#{name}.mp3"
|
134
|
+
else
|
135
|
+
Tempfile.new(['souncloud', '.mp3'])
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soundcloud-downloader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gabriel Dehan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-19 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A simple API to download soundcloud songs
|
14
|
+
email: dehan.gabriel@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/soundcloud-downloader.rb
|
20
|
+
homepage: http://rubygems.org/gems/soundcloud-downloader
|
21
|
+
licenses:
|
22
|
+
- WTFPL
|
23
|
+
metadata: {}
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
requirements: []
|
39
|
+
rubyforge_project:
|
40
|
+
rubygems_version: 2.4.5.1
|
41
|
+
signing_key:
|
42
|
+
specification_version: 4
|
43
|
+
summary: A simple API to download soundcloud songs
|
44
|
+
test_files: []
|
45
|
+
has_rdoc:
|