get_them_all 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.
- 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: []
|