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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/soundcloud-downloader.rb +140 -0
  3. metadata +45 -0
@@ -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: