get_them_all 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README.md +77 -0
- data/bin/gta +54 -0
- data/get_them_all.gemspec +28 -0
- data/lib/get_them_all.rb +47 -0
- data/lib/get_them_all/action.rb +55 -0
- data/lib/get_them_all/actions/download_action.rb +80 -0
- data/lib/get_them_all/actions/examine_action.rb +47 -0
- data/lib/get_them_all/extension.rb +17 -0
- data/lib/get_them_all/extensions/action_logger.rb +58 -0
- data/lib/get_them_all/extensions/gauge_display.rb +155 -0
- data/lib/get_them_all/extensions/graph_builder.rb +138 -0
- data/lib/get_them_all/history.rb +23 -0
- data/lib/get_them_all/javascript_loader.rb +74 -0
- data/lib/get_them_all/logger.rb +35 -0
- data/lib/get_them_all/notifier.rb +7 -0
- data/lib/get_them_all/site_downloader.rb +332 -0
- data/lib/get_them_all/storage.rb +27 -0
- data/lib/get_them_all/storage/dropbox_storage.rb +114 -0
- data/lib/get_them_all/storage/file_storage.rb +40 -0
- data/lib/get_them_all/version.rb +3 -0
- data/lib/get_them_all/worker.rb +48 -0
- metadata +172 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module GetThemAll
|
2
|
+
class Storage
|
3
|
+
|
4
|
+
class StorageError < RuntimeError; end
|
5
|
+
class WriteError < StorageError; end
|
6
|
+
class ReadError < StorageError; end
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@root = options.delete(:root)
|
10
|
+
@folder_name = options.delete(:folder_name)
|
11
|
+
raise "missing required option: folder_name" unless @folder_name
|
12
|
+
raise "missing required option: root" unless @root
|
13
|
+
|
14
|
+
@root = File.join(@root, @folder_name)
|
15
|
+
raise "missing required option: root" unless @root
|
16
|
+
end
|
17
|
+
|
18
|
+
def working?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_destpath(path)
|
23
|
+
File.join(@root, path)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'dropbox'
|
3
|
+
require 'girl_friday'
|
4
|
+
|
5
|
+
module GetThemAll
|
6
|
+
class DropboxStorage < Storage
|
7
|
+
|
8
|
+
|
9
|
+
# def self.deserialize(data)
|
10
|
+
# consumer_key, consumer_secret, authorized, token, token_secret, ssl, mode = YAML.load(StringIO.new(data))
|
11
|
+
# raise ArgumentError, "Must provide a properly serialized #{self.to_s} instance" unless [ consumer_key, consumer_secret, token, token_secret ].all? and authorized == true or authorized == false
|
12
|
+
#
|
13
|
+
# session = self.new(consumer_key, consumer_secret, :ssl => ssl, :already_authorized => authorized)
|
14
|
+
# if authorized then
|
15
|
+
# session.set_access_token token, token_secret
|
16
|
+
# else
|
17
|
+
# session.set_request_token token, token_secret
|
18
|
+
# end
|
19
|
+
# session.mode = mode if mode
|
20
|
+
#
|
21
|
+
# return session
|
22
|
+
# end
|
23
|
+
|
24
|
+
def initialize(options = {})
|
25
|
+
super
|
26
|
+
|
27
|
+
session_data = options.delete(:session)
|
28
|
+
raise "session missing" unless session_data
|
29
|
+
|
30
|
+
consumer_key, consumer_secret, authorized, token, token_secret, ssl, mode = session_data
|
31
|
+
|
32
|
+
@session = Dropbox::Session.new(consumer_key, consumer_secret, :ssl => ssl, :already_authorized => authorized)
|
33
|
+
@session.set_access_token(token, token_secret)
|
34
|
+
@session.mode = mode.to_sym
|
35
|
+
|
36
|
+
@queue = GirlFriday::WorkQueue.new(:dropbox_upload, :size => 1) do |msg|
|
37
|
+
# puts "Uploading file #{msg[:path]}..."
|
38
|
+
write(msg[:path], msg[:data], false, msg[:deferrable])
|
39
|
+
# puts "Upload ok."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Can we exit or is there still some work to do ?
|
45
|
+
#
|
46
|
+
# @return [Boolean]
|
47
|
+
#
|
48
|
+
def working?
|
49
|
+
s = @queue.status['dropbox_upload']
|
50
|
+
(s[:backlog] > 0) || (s[:busy] > 0)
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Check if the remote file/folder exists,
|
55
|
+
# there may be a better way but it works.
|
56
|
+
#
|
57
|
+
# @return [Boolean] true if the remote path exists
|
58
|
+
#
|
59
|
+
def exist?(path)
|
60
|
+
destpath = build_destpath(path)
|
61
|
+
|
62
|
+
metadata = @session.metadata(destpath)
|
63
|
+
if metadata.respond_to?(:is_deleted) && metadata.is_deleted
|
64
|
+
false
|
65
|
+
else
|
66
|
+
true
|
67
|
+
end
|
68
|
+
rescue Dropbox::FileNotFoundError
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Write data in a remote file.
|
74
|
+
# Folders in the path will be automatically created as
|
75
|
+
# needed.
|
76
|
+
#
|
77
|
+
def write(path, data, delay = true, deferrable = EM::DefaultDeferrable.new)
|
78
|
+
retries = 0
|
79
|
+
|
80
|
+
if delay
|
81
|
+
@queue.push(:path => path, :data => data, :deferrable => deferrable)
|
82
|
+
else
|
83
|
+
destpath = build_destpath(path)
|
84
|
+
filename, dirname = File.basename(destpath), File.dirname(destpath)
|
85
|
+
@session.upload(StringIO.new(data), dirname, :as => filename)
|
86
|
+
EM::next_tick{ deferrable.succeed }
|
87
|
+
end
|
88
|
+
|
89
|
+
deferrable
|
90
|
+
rescue => err
|
91
|
+
if retries < 4
|
92
|
+
# puts "[#{retries}] Upload error, retrying: #{err}"
|
93
|
+
retries += 1
|
94
|
+
retry
|
95
|
+
else
|
96
|
+
EM::next_tick{ deferrable.fail }
|
97
|
+
raise WriteError, "cannot write file: #{err}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Read file's content and return it.
|
103
|
+
#
|
104
|
+
# @return [String] file's content
|
105
|
+
#
|
106
|
+
def read(path)
|
107
|
+
destpath = build_destpath(path)
|
108
|
+
@session.download(destpath)
|
109
|
+
rescue => err
|
110
|
+
raise ReadError, "cannot read file: #{err}"
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module GetThemAll
|
2
|
+
class FileStorage < Storage
|
3
|
+
|
4
|
+
# def initialize(options = {})
|
5
|
+
# super
|
6
|
+
# end
|
7
|
+
|
8
|
+
def exist?(path)
|
9
|
+
destpath = build_destpath(path)
|
10
|
+
File.exist?(destpath)
|
11
|
+
end
|
12
|
+
|
13
|
+
def write(path, data)
|
14
|
+
deferrable = EM::DefaultDeferrable.new
|
15
|
+
|
16
|
+
destpath = build_destpath(path)
|
17
|
+
FileUtils.mkdir_p( File.dirname(destpath) )
|
18
|
+
open(destpath, "wb") do |f|
|
19
|
+
f.write( data )
|
20
|
+
end
|
21
|
+
|
22
|
+
deferrable.succeed
|
23
|
+
deferrable
|
24
|
+
|
25
|
+
rescue Errno::EINVAL
|
26
|
+
deferrable.fail
|
27
|
+
raise Storage::WriteError("cannot write file")
|
28
|
+
end
|
29
|
+
|
30
|
+
def read(path)
|
31
|
+
destpath = build_destpath(path)
|
32
|
+
if File.readable?(destpath)
|
33
|
+
File.read(destpath)
|
34
|
+
else
|
35
|
+
raise Storage::ReadError("cannot open file")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module GetThemAll
|
2
|
+
#
|
3
|
+
# workers are created to follow a queue
|
4
|
+
# each time an action is put in the queue it will handle it
|
5
|
+
#
|
6
|
+
class Worker
|
7
|
+
attr_reader :type, :index
|
8
|
+
|
9
|
+
def initialize(type, index, downloader, queue)
|
10
|
+
@type = type
|
11
|
+
@index = index
|
12
|
+
|
13
|
+
@downloader = downloader
|
14
|
+
@queue = queue
|
15
|
+
|
16
|
+
@queue.pop do |action|
|
17
|
+
handle_action(action)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Take the next action in queue
|
24
|
+
#
|
25
|
+
def take_next_job
|
26
|
+
EM::next_tick do
|
27
|
+
@queue.pop{|act| handle_action(act) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def handle_action(action)
|
33
|
+
action.callback( &method(:take_next_job) )
|
34
|
+
action.errback do
|
35
|
+
# in case of failure, try again later (with slightly lower priority)
|
36
|
+
EM::add_timer(50) do
|
37
|
+
@queue.push(action, [action.level - 1, 0].max)
|
38
|
+
end
|
39
|
+
|
40
|
+
# and take the next job
|
41
|
+
take_next_job()
|
42
|
+
end
|
43
|
+
|
44
|
+
action.do_action(self)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: get_them_all
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Julien Ammous
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-16 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: &70256844459680 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70256844459680
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: em-http-request
|
27
|
+
requirement: &70256844459180 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70256844459180
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: em-priority-queue
|
38
|
+
requirement: &70256844458680 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.0.2
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70256844458680
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: hpricot
|
49
|
+
requirement: &70256844458220 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.1
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70256844458220
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: i18n
|
60
|
+
requirement: &70256844457840 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70256844457840
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activesupport
|
71
|
+
requirement: &70256844457300 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 3.1.0
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70256844457300
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: therubyracer
|
82
|
+
requirement: &70256844456800 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.9.8
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70256844456800
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: dropbox
|
93
|
+
requirement: &70256844456420 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70256844456420
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: girl_friday
|
104
|
+
requirement: &70256844455800 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :runtime
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *70256844455800
|
113
|
+
description: Mass downloader useable as standalone or as a library
|
114
|
+
email: []
|
115
|
+
executables:
|
116
|
+
- gta
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- LICENSE
|
121
|
+
- README.md
|
122
|
+
- get_them_all.gemspec
|
123
|
+
- lib/get_them_all.rb
|
124
|
+
- lib/get_them_all/action.rb
|
125
|
+
- lib/get_them_all/actions/download_action.rb
|
126
|
+
- lib/get_them_all/actions/examine_action.rb
|
127
|
+
- lib/get_them_all/extension.rb
|
128
|
+
- lib/get_them_all/extensions/action_logger.rb
|
129
|
+
- lib/get_them_all/extensions/gauge_display.rb
|
130
|
+
- lib/get_them_all/extensions/graph_builder.rb
|
131
|
+
- lib/get_them_all/history.rb
|
132
|
+
- lib/get_them_all/javascript_loader.rb
|
133
|
+
- lib/get_them_all/logger.rb
|
134
|
+
- lib/get_them_all/notifier.rb
|
135
|
+
- lib/get_them_all/site_downloader.rb
|
136
|
+
- lib/get_them_all/storage.rb
|
137
|
+
- lib/get_them_all/storage/dropbox_storage.rb
|
138
|
+
- lib/get_them_all/storage/file_storage.rb
|
139
|
+
- lib/get_them_all/version.rb
|
140
|
+
- lib/get_them_all/worker.rb
|
141
|
+
- bin/gta
|
142
|
+
homepage: ''
|
143
|
+
licenses: []
|
144
|
+
post_install_message:
|
145
|
+
rdoc_options: []
|
146
|
+
require_paths:
|
147
|
+
- lib
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
segments:
|
155
|
+
- 0
|
156
|
+
hash: 3600791884245333025
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
none: false
|
159
|
+
requirements:
|
160
|
+
- - ! '>='
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
segments:
|
164
|
+
- 0
|
165
|
+
hash: 3600791884245333025
|
166
|
+
requirements: []
|
167
|
+
rubyforge_project: get_them_all
|
168
|
+
rubygems_version: 1.8.11
|
169
|
+
signing_key:
|
170
|
+
specification_version: 3
|
171
|
+
summary: Mass downloader
|
172
|
+
test_files: []
|