wwdcdownloader 20.13.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/Gemfile +16 -0
- data/Gemfile.lock +49 -0
- data/LICENSE.txt +20 -0
- data/Rakefile +25 -0
- data/Readme.md +22 -0
- data/VERSION +1 -0
- data/bin/wwdcdownloader +6 -0
- data/lib/wwdcdownloader.rb +240 -0
- metadata +164 -0
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
# If you make any changes in this file, please run `bundle install`.
|
4
|
+
# If new versions of your installed gems are available, run `bundle update`
|
5
|
+
|
6
|
+
gem "mechanize", "~> 2.7.1"
|
7
|
+
gem "json", "~> 1.8.0"
|
8
|
+
gem "highline", "~> 1.6.19"
|
9
|
+
gem "nokogiri", "~> 1.5.0"
|
10
|
+
|
11
|
+
group :development do
|
12
|
+
#gem "shoulda", ">= 0"
|
13
|
+
gem "bundler", "~> 1.0.0"
|
14
|
+
gem "jeweler", "~> 1.8.0"
|
15
|
+
gem "rcov", ">= 0"
|
16
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
domain_name (0.5.12)
|
5
|
+
unf (>= 0.0.5, < 1.0.0)
|
6
|
+
git (1.2.5)
|
7
|
+
highline (1.6.19)
|
8
|
+
http-cookie (1.0.1)
|
9
|
+
domain_name (~> 0.5)
|
10
|
+
jeweler (1.8.4)
|
11
|
+
bundler (~> 1.0)
|
12
|
+
git (>= 1.2.5)
|
13
|
+
rake
|
14
|
+
rdoc
|
15
|
+
json (1.8.0)
|
16
|
+
mechanize (2.7.1)
|
17
|
+
domain_name (~> 0.5, >= 0.5.1)
|
18
|
+
http-cookie (~> 1.0.0)
|
19
|
+
mime-types (~> 1.17, >= 1.17.2)
|
20
|
+
net-http-digest_auth (~> 1.1, >= 1.1.1)
|
21
|
+
net-http-persistent (~> 2.5, >= 2.5.2)
|
22
|
+
nokogiri (~> 1.4)
|
23
|
+
ntlm-http (~> 0.1, >= 0.1.1)
|
24
|
+
webrobots (>= 0.0.9, < 0.2)
|
25
|
+
mime-types (1.23)
|
26
|
+
net-http-digest_auth (1.3)
|
27
|
+
net-http-persistent (2.8)
|
28
|
+
nokogiri (1.5.10)
|
29
|
+
ntlm-http (0.1.1)
|
30
|
+
rake (10.0.4)
|
31
|
+
rcov (0.9.9)
|
32
|
+
rdoc (4.0.1)
|
33
|
+
json (~> 1.4)
|
34
|
+
unf (0.1.1)
|
35
|
+
unf_ext
|
36
|
+
unf_ext (0.0.6)
|
37
|
+
webrobots (0.1.1)
|
38
|
+
|
39
|
+
PLATFORMS
|
40
|
+
ruby
|
41
|
+
|
42
|
+
DEPENDENCIES
|
43
|
+
bundler (~> 1.0.0)
|
44
|
+
highline (~> 1.6.19)
|
45
|
+
jeweler (~> 1.8.0)
|
46
|
+
json (~> 1.8.0)
|
47
|
+
mechanize (~> 2.7.1)
|
48
|
+
nokogiri (~> 1.5.0)
|
49
|
+
rcov
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Johannes Fahrenkrug
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "wwdcdownloader"
|
16
|
+
gem.homepage = "https://github.com/jfahrenkrug/WWDC-Downloader"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{A small tool to download all the sample code of Apple's latest WWDC developer conference}
|
19
|
+
gem.description = %Q{At each year's WWDC, Apple releases great sample projects. Unfortunately it is very tedious to manually download all these treasures through your browser. WWDC-Downloader solves this problem for you!}
|
20
|
+
gem.email = "johannes@springenwerk.com"
|
21
|
+
gem.authors = ["Johannes Fahrenkrug"]
|
22
|
+
|
23
|
+
# dependencies defined in Gemfile
|
24
|
+
end
|
25
|
+
Jeweler::RubygemsDotOrgTasks.new
|
data/Readme.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# WWDC 2013 Sample Code Downloader
|
2
|
+
|
3
|
+

|
4
|
+
|
5
|
+
## Sad days are over
|
6
|
+
|
7
|
+
This script will download all the session material for you if you are a WWDC 2013 attendee OR NOT! This year you only need to have an Apple Developer account, that's it!
|
8
|
+
You can now simply install WWDC-Downloader as a ruby gem like this:
|
9
|
+
|
10
|
+
gem install wwdcdownloader
|
11
|
+
|
12
|
+
or
|
13
|
+
|
14
|
+
sudo gem install wwdcdownloader
|
15
|
+
|
16
|
+
Run the script like this:
|
17
|
+
|
18
|
+
wwdcdownloader <your Apple ID> [<target-dir>]
|
19
|
+
|
20
|
+
The script will create a directory called "wwdc2013-assets" (or <target-dir> if given) in the directory you run the script from.
|
21
|
+
|
22
|
+
That's it. Enjoy and see you next year.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
20.13.0
|
data/bin/wwdcdownloader
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
# Have fun. Use at your own risk.
|
2
|
+
# Copyright (c) 2013 Johannes Fahrenkrug
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'net/http'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'mechanize'
|
10
|
+
require 'json'
|
11
|
+
require 'highline/import'
|
12
|
+
rescue LoadError => e
|
13
|
+
puts
|
14
|
+
puts "You need to have the mechanize, json and highline gems installed."
|
15
|
+
puts "Install them by running"
|
16
|
+
puts
|
17
|
+
puts " bundle install"
|
18
|
+
puts
|
19
|
+
puts "and then run the script like this:"
|
20
|
+
puts
|
21
|
+
puts " bundle exec ruby lib/wwdcdownloader.rb"
|
22
|
+
puts
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
class WWDCDownloader
|
27
|
+
BASE_URI = 'https://developer.apple.com/wwdc-services/cy4p09ns/a4363cb15472b00287b/sessions.json'
|
28
|
+
|
29
|
+
WWDC_LIBRARIES = [{:base => 'https://developer.apple.com/library/prerelease/ios', :lib => '/navigation/library.json'},
|
30
|
+
{:base => 'https://developer.apple.com/library/prerelease/mac', :lib => '/navigation/library.json'}]
|
31
|
+
|
32
|
+
attr_accessor :downloaded_files, :dl_dir, :mech, :min_date
|
33
|
+
|
34
|
+
def initialize(dl_dir, min_date)
|
35
|
+
self.dl_dir = dl_dir
|
36
|
+
self.min_date = min_date
|
37
|
+
self.mech = Mechanize.new
|
38
|
+
self.downloaded_files = []
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates the given directory if it doesn't exist already.
|
42
|
+
def mkdir(dir)
|
43
|
+
if File.exists?(dir)
|
44
|
+
false
|
45
|
+
else
|
46
|
+
Dir.mkdir dir
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Login
|
52
|
+
def login
|
53
|
+
wrong_password = true
|
54
|
+
|
55
|
+
while wrong_password do
|
56
|
+
password = ask("Enter your ADC password: ") { |q| q.echo = "*" }
|
57
|
+
|
58
|
+
self.mech.get('https://developer.apple.com/wwdc/videos/') do |page|
|
59
|
+
my_page = page.form_with(:name => 'appleConnectForm') do |f|
|
60
|
+
f.theAccountName = ARGV[0]
|
61
|
+
f.theAccountPW = password
|
62
|
+
end.click_button
|
63
|
+
|
64
|
+
if my_page.body =~ /incorrect/
|
65
|
+
puts "Wrong password, please try again."
|
66
|
+
else
|
67
|
+
wrong_password = false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def download_sample_code_from_book_json(book_json_url, code_base_url, dest_dir, duplicates_ok)
|
74
|
+
did_download = false
|
75
|
+
self.mech.get(book_json_url) do |book_json|
|
76
|
+
if book_json.body[0,1] == '<'
|
77
|
+
puts " Sorry, this samplecode apparently isn't available yet: #{code_base_url}/book.json"
|
78
|
+
else
|
79
|
+
book_res = JSON.parse(book_json.body)
|
80
|
+
filename = book_res["sampleCode"]
|
81
|
+
url = "#{code_base_url}/#{filename}"
|
82
|
+
|
83
|
+
if duplicates_ok or !self.downloaded_files.include?(url)
|
84
|
+
# remember what we downloaded
|
85
|
+
self.downloaded_files << url
|
86
|
+
|
87
|
+
puts " Downloading #{url}"
|
88
|
+
begin
|
89
|
+
self.mech.get(url) do |downloaded_file|
|
90
|
+
open(dest_dir + "/" + filename, 'wb') do |file|
|
91
|
+
file.write(downloaded_file.body)
|
92
|
+
end
|
93
|
+
did_download = true
|
94
|
+
end
|
95
|
+
rescue Exception => e
|
96
|
+
puts " Download failed #{e}"
|
97
|
+
end
|
98
|
+
elsif !duplicates_ok
|
99
|
+
puts " Already downloaded this file, skipping."
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
did_download
|
105
|
+
end
|
106
|
+
|
107
|
+
def download_sample_code_for_page(a_page_url, dest_dir, duplicates_ok = true)
|
108
|
+
self.mech.get(a_page_url) do |page|
|
109
|
+
has_samplecode = false
|
110
|
+
page.links_with(:href => %r{/samplecode/} ).each do |link|
|
111
|
+
has_samplecode = true
|
112
|
+
code_base_url = File.dirname(link.href)
|
113
|
+
|
114
|
+
download_sample_code_from_book_json("#{code_base_url}/book.json", code_base_url, dest_dir, duplicates_ok)
|
115
|
+
end
|
116
|
+
|
117
|
+
if !has_samplecode
|
118
|
+
puts " Sorry, this session doesn't have samplecode, cleaning up."
|
119
|
+
begin
|
120
|
+
Dir.delete( dest_dir )
|
121
|
+
rescue
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def load
|
129
|
+
mkdir(dl_dir)
|
130
|
+
|
131
|
+
# get the sessions JSON
|
132
|
+
self.mech.get(BASE_URI) do |page|
|
133
|
+
res = JSON.parse(page.body)
|
134
|
+
|
135
|
+
# Was there an error?
|
136
|
+
error = res['response']['error']
|
137
|
+
|
138
|
+
if (error)
|
139
|
+
STDERR.puts " Apple's API returned an error: '#{error}'"
|
140
|
+
exit
|
141
|
+
end
|
142
|
+
|
143
|
+
sessions = res['response']['sessions']
|
144
|
+
|
145
|
+
if sessions.size > 0
|
146
|
+
|
147
|
+
sessions.each do |session|
|
148
|
+
if session['type'] == 'Session'
|
149
|
+
title = session['title']
|
150
|
+
session_id = session['id']
|
151
|
+
puts "Session #{session_id} '#{title}'..."
|
152
|
+
|
153
|
+
# get the files
|
154
|
+
dirname = "#{dl_dir}/#{session_id}-#{title.gsub(/\/|&|!/, '')}"
|
155
|
+
puts " Creating #{dirname}"
|
156
|
+
mkdir(dirname)
|
157
|
+
|
158
|
+
begin
|
159
|
+
download_sample_code_for_page(session['url'], dirname)
|
160
|
+
rescue Mechanize::ResponseCodeError => e
|
161
|
+
STDERR.puts " Error retrieving list for session. Proceeding with next session (#{$!})"
|
162
|
+
next
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
else
|
167
|
+
print "No sessions :(.\n"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# scrape the WWDC libraries...
|
172
|
+
puts
|
173
|
+
puts "Scraping the WWDC libraries (not all sample code might be linked up correctly yet)"
|
174
|
+
WWDC_LIBRARIES.each do |lib_hash|
|
175
|
+
lib = "#{lib_hash[:base]}#{lib_hash[:lib]}"
|
176
|
+
self.mech.get(lib) do |page|
|
177
|
+
body = page.body.gsub("''", '""')
|
178
|
+
res = JSON.parse(body)
|
179
|
+
|
180
|
+
docs = res['documents']
|
181
|
+
|
182
|
+
if docs.size > 0
|
183
|
+
|
184
|
+
docs.each do |doc|
|
185
|
+
if doc[2] == 5 and doc[3] >= self.min_date # sample code and newer or equal to min date
|
186
|
+
title = doc[0]
|
187
|
+
|
188
|
+
puts "Sample Code '#{title}'..."
|
189
|
+
|
190
|
+
# get the files
|
191
|
+
dirname = "#{dl_dir}/#{title.gsub(/\/|&|!/, '')}"
|
192
|
+
puts " Creating #{dirname}"
|
193
|
+
did_create_dir = mkdir(dirname)
|
194
|
+
|
195
|
+
segments = doc[9].split('/')
|
196
|
+
url = "#{lib_hash[:base]}/samplecode/#{segments[2]}/book.json"
|
197
|
+
|
198
|
+
begin
|
199
|
+
puts url
|
200
|
+
did_download = download_sample_code_from_book_json(url, "#{lib_hash[:base]}/samplecode/#{segments[2]}", dirname, false)
|
201
|
+
if !did_download and did_create_dir
|
202
|
+
Dir.delete( dirname )
|
203
|
+
end
|
204
|
+
rescue Mechanize::ResponseCodeError => e
|
205
|
+
STDERR.puts " Error retrieving list for sample code. Proceeding with next one (#{$!})"
|
206
|
+
next
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
else
|
211
|
+
print "No code samples :(.\n"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
puts "Done."
|
217
|
+
end
|
218
|
+
|
219
|
+
def self.run!(*args)
|
220
|
+
puts "WWDC 2013 Session Material Downloader"
|
221
|
+
puts "by Johannes Fahrenkrug, @jfahrenkrug, springenwerk.com"
|
222
|
+
puts "See you next year!"
|
223
|
+
puts
|
224
|
+
|
225
|
+
if args.size < 1
|
226
|
+
puts "Usage: wwdcdownloader <your Apple ID> [<target-dir>]"
|
227
|
+
exit
|
228
|
+
end
|
229
|
+
|
230
|
+
dl_dir = if args.size > 1
|
231
|
+
args.last
|
232
|
+
else
|
233
|
+
'wwdc2013-assets'
|
234
|
+
end
|
235
|
+
|
236
|
+
w = WWDCDownloader.new(dl_dir, '2013-06-10')
|
237
|
+
w.login
|
238
|
+
w.load
|
239
|
+
end
|
240
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wwdcdownloader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 20
|
7
|
+
- 13
|
8
|
+
- 0
|
9
|
+
version: 20.13.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Johannes Fahrenkrug
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2013-06-12 00:00:00 +02:00
|
18
|
+
default_executable: wwdcdownloader
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
prerelease: false
|
22
|
+
type: :runtime
|
23
|
+
name: mechanize
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 7
|
31
|
+
- 1
|
32
|
+
version: 2.7.1
|
33
|
+
requirement: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
prerelease: false
|
36
|
+
type: :runtime
|
37
|
+
name: json
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
segments:
|
43
|
+
- 1
|
44
|
+
- 8
|
45
|
+
- 0
|
46
|
+
version: 1.8.0
|
47
|
+
requirement: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
prerelease: false
|
50
|
+
type: :runtime
|
51
|
+
name: highline
|
52
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ~>
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 1
|
58
|
+
- 6
|
59
|
+
- 19
|
60
|
+
version: 1.6.19
|
61
|
+
requirement: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
prerelease: false
|
64
|
+
type: :runtime
|
65
|
+
name: nokogiri
|
66
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 1
|
72
|
+
- 5
|
73
|
+
- 0
|
74
|
+
version: 1.5.0
|
75
|
+
requirement: *id004
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
prerelease: false
|
78
|
+
type: :development
|
79
|
+
name: bundler
|
80
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ~>
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
segments:
|
85
|
+
- 1
|
86
|
+
- 0
|
87
|
+
- 0
|
88
|
+
version: 1.0.0
|
89
|
+
requirement: *id005
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
prerelease: false
|
92
|
+
type: :development
|
93
|
+
name: jeweler
|
94
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 1
|
100
|
+
- 8
|
101
|
+
- 0
|
102
|
+
version: 1.8.0
|
103
|
+
requirement: *id006
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
prerelease: false
|
106
|
+
type: :development
|
107
|
+
name: rcov
|
108
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
segments:
|
113
|
+
- 0
|
114
|
+
version: "0"
|
115
|
+
requirement: *id007
|
116
|
+
description: At each year's WWDC, Apple releases great sample projects. Unfortunately it is very tedious to manually download all these treasures through your browser. WWDC-Downloader solves this problem for you!
|
117
|
+
email: johannes@springenwerk.com
|
118
|
+
executables:
|
119
|
+
- wwdcdownloader
|
120
|
+
extensions: []
|
121
|
+
|
122
|
+
extra_rdoc_files:
|
123
|
+
- LICENSE.txt
|
124
|
+
files:
|
125
|
+
- Gemfile
|
126
|
+
- Gemfile.lock
|
127
|
+
- LICENSE.txt
|
128
|
+
- Rakefile
|
129
|
+
- Readme.md
|
130
|
+
- VERSION
|
131
|
+
- bin/wwdcdownloader
|
132
|
+
- lib/wwdcdownloader.rb
|
133
|
+
has_rdoc: true
|
134
|
+
homepage: https://github.com/jfahrenkrug/WWDC-Downloader
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
segments:
|
147
|
+
- 0
|
148
|
+
version: "0"
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
segments:
|
154
|
+
- 0
|
155
|
+
version: "0"
|
156
|
+
requirements: []
|
157
|
+
|
158
|
+
rubyforge_project:
|
159
|
+
rubygems_version: 1.3.6
|
160
|
+
signing_key:
|
161
|
+
specification_version: 3
|
162
|
+
summary: A small tool to download all the sample code of Apple's latest WWDC developer conference
|
163
|
+
test_files: []
|
164
|
+
|