forked from bf4/book_code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbooks.rb
207 lines (207 loc) · 10.2 KB
/
books.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
books = {
'dswdcloj' => {
name: "Web Development with Clojure: Build Bulletproof Web Apps with Less Code",
author: "Dmitri Sotnikov",
printing: "P2.0",
published: "2014-01-15",
printed: "2014-07-30",
releases: "https://pragprog.com/titles/dswdcloj/release_info",
source_code: "http://media.pragprog.com/titles/dswdcloj/code/dswdcloj-code.tgz",
artifacts: [
{ name: "Clojure Distilled", link: "http://media.pragprog.com/titles/dswdcloj/ClojureDistilled.pdf"},
],
},
'7lang' => { name: "Seven More Languages in Seven Weeks: Languages That Are Shaping the Future" },
'7web' => { name: "Seven Web Frameworks in Seven Weeks: Adventures in Better Web Apps" },
'achbd' => { name: "The RSpec Book: Behaviour-Driven Development with RSpec, Cucumber, and Friends" },
'adio2' => { name: "iOS 8 SDK Development" },
'adios2' => { name: "iOS 8 SDK Development: Creating iPhone and iPad Apps with Swift" },
'adrpo' => { name: "Ruby Performance Optimization" },
'ahmine2' => { name: "Learn to Program with Minecraft Plugins (2nd edition): Create Flaming Cows in Java Using CanaryMod" },
'atcrime' => { name: "Your Code As a Crime Scene: Use Forensic Techniques to Arrest Defects, Bottlenecks, and Bad Design in Your Programs" },
'bhgrunt' => { name: "Automate with Grunt: The Build Tool for JavaScript" },
'bhgwad' => { name: "Web Design for Developers: A Programmer's Guide to Design Tools and Techniques" },
'bhh5' => {},
'bhh52e' => { name: "HTML5 and CSS3 (2nd edition): Level Up with Today's Web Technologies" },
'bhtmux' => { name: "tmux: Productive Mouse-Free Development" },
'bksqla' => { name: "SQL Antipatterns: Avoiding the Pitfalls of Database Programming" },
'bkviml' => { name: "The VimL Primer: Edit Like a Pro with Vim Plugins and Scripts" },
'bmsft' => { name: "Everyday Scripting with Ruby: for Teams, Testers, and You" },
'bhwb' => { name: "Exercises for Programmers: 57 Challenges to Develop Your Coding Skills" },
'btlang' => { name: "Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages" },
'cbdepra' => { name: "Deploying Rails: Automate, Deploy, Scale, Maintain, and Sleep at Night" },
'cjclojure' => { name: "Mastering Clojure Macros: Write Cleaner, Faster, Smarter Code" },
'cmelixir' => { name: "Metaprogramming Elixir" },
'd-dsbackm' => { name: "Backbone Marionette" },
'dcbang' => { name: "Rails, Angular, Postgres, and Bootstrap" },
'dccar' => {},
'dccar2' => { name: "Build Awesome Command-Line Applications in Ruby 2: Control Your Computer, Simplify Your Life" },
'dhwcr' => { name: "Cucumber Recipes: Automate Anything with BDD Tools and Techniques" },
'djkxsl' => { name: "XSLT Jumpstarter" },
'dnvim' => { name: "Practical Vim: Edit Text at the Speed of Thought" },
'dsproc' => { name: "Rapid Android Development: Build Rich, Sensor-Based Applications with Processing" },
'eband4' => { name: "Hello, Android (4th edition)" },
'elixir' => { name: "Programming Elixir: Functional |> Concurrent |> Pragmatic |> Fun" },
'erpgg2' => { name: "Programming Google Glass (2nd edition): Build Great Glassware Apps with the Mirror API and GDK" },
'fr_quiz' => { name: "Best of Ruby Quiz" },
'fr_secure' => { name: "Security on Rails" },
'gwpy2' => { name: "Practical Programming (2nd edition): An Introduction to Computer Science Using Python 3" },
'hwcuc' => { name: "The Cucumber Book: Behaviour-Driven Development for Testers and Developers" },
'idgtr' => { name: "Scripted GUI Testing with Ruby" },
'jaerlang2' => { name: "Programming Erlang (2nd edition)" },
'jbmaze' => { name: "Mazes for Programmers" },
'jkdepj' => { name: "Deploying with JRuby: Deliver Scalable Web Apps using the JVM" },
'jkrp' => { name: "Remote Pairing: Collaborative Tools for Distributed Development" },
'jruby' => { name: "Using JRuby: Bringing Ruby to Java" },
'jsaccess' => { name: "Design Accessible Web Sites: 36 Keys to Creating Content for All Audiences and Platforms" },
'jstcp' => { name: "Working with TCP Sockets" },
'jsthreads' => { name: "Working with Ruby Threads" },
'jsunix' => { name: "Working with Unix Processes" },
'jvrails2' => { name: "Crafting Rails 4 Applications: Expert Practices for Everyday Rails Development" },
'jwnode' => { name: "Node.js the Right Way: Practical, Server-Side JavaScript That Scales" },
'kcdc' => { name: "The Developer's Code: What Real Programmers Do" },
'kdnodesec' => { name: "Secure Your Node.js Web Application" },
'mbfpp' => { name: "Functional Programming Patterns in Scala and Clojure: Write Lean Programs for the JVM" },
'msard2' => { name: "Arduino: A Quick-Start Guide, Second Edition" },
'mwjsember' => { name: "Deliver Audacious Web Apps with Ember 2" },
'msgpkids' => { name: "Learn Game Programming with Ruby: Bring Your Ideas to Life with Gosu" },
'nrtest' => {},
'nrtest2' => { name: "Rails 4 Test Prescriptions: Build a Healthy Codebase" },
'pb7con' => { name: "Seven Concurrency Models in Seven Weeks: When Threads Unravel" },
'pg_git' => { name: "Pragmatic Guide to Git" },
'pg_sass' => { name: "Pragmatic Guide to Sass" },
'ppmetr' => {},
'ppmetr2' => { name: "Metaprogramming Ruby 2: Program Like the Ruby Pros" },
'rails4' => { name: "Agile Web Development with Rails 4" },
'rcctr' => { name: "Continuous Testing: with Ruby, Rails, and JavaScript" },
'rjnsd' => { name: "The Nature of Software Development: Keep It Simple, Make It Valuable, Build It Piece by Piece" },
'rmtpruby' => { name: "Text Processing with Ruby" },
'rr2' => { name: "Rails Recipes: Rails 3 Edition" },
'ruby4' => { name: "Programming Ruby 1.9 & 2.0 (4th edition): The Pragmatic Programmers' Guide" },
'rwdata' => { name: "Seven Databases in Seven Weeks: A Guide to Modern Databases and the NoSQL Movement" },
'shcloj2' => { name: "Programming Clojure (2nd edition)" },
'sidruby' => { name: "The dRuby Book: Distributed and Parallel Computing with Ruby" },
'tbajs' => { name: "Async JavaScript: Build More Responsive Apps with Less Code" },
'tbcoffee' => {},
'tbcoffee2' => { name: "CoffeeScript: Accelerated JavaScript Development, Second Edition" },
'vmclojeco' => { name: "Clojure Applied: From Practice to Practitioner" },
'vsscala2' => { name: "Pragmatic Scala" },
'warv' => { name: "The Rails View: Create a Beautiful and Maintainable User Experience" },
'wbdev' => { name: "Web Development Recipes" },
'wbdev2' => { name: "Web Development Recipes 2nd Edition" },
}.reject {|_,v| v.empty? }
# source code page 404's (no code yet)
# {
# }
# these aren't pragprog
# these have no source code
# {
# 'ktmack2' => { name: "Mac Kung Fu (2nd edition): Over 400 Tips, Tricks, Hints, and Hacks for Apple OS X" },
# 'd-kegrap' => { name: "Growing Rails Applications in Practice" },
# 'd-dbback' => { name: "Building Backbone Plugins" },
# 'agcr' => { name: "Confident Ruby" },
# 'ltp2' => { name: "Learn to Program (2nd edition)" },
# https://pragprog.com/book/ebdojo/the-coding-dojo-handbook
# https://pragprog.com/book/pkretro/the-retrospective-handbook
# https://pragprog.com/book/ec101di/101-design-ingredients-to-solve-big-tech-problems
# https://pragprog.com/book/nbapp/the-app-design-handbook
# https://pragprog.com/book/smacss/scalable-and-modular-architecture-for-css
# https://pragprog.com/book/csspdy/the-spdy-book
# }
require 'fileutils'
def in_dir(dirname, &block)
FileUtils.mkdir_p(dirname)
Dir.chdir(dirname,&block)
end
def extract_code?
not File.directory?("code")
end
def tar_file(prag_ref)
@tar_file ||= {}
@tar_file.fetch(prag_ref) do
@tar_file[prag_ref] = "#{prag_ref}-code.tgz"
end
end
def download_code?(tarball)
not File.file?(tarball)
end
def download_code(source_code)
filename = File.basename(source_code)
puts `curl -q -L #{source_code} -o #{filename}`
# need error handling and messaging
if $?.success?
true
else
STDERR.puts "Failed downloading #{prag_ref} code #{$?.class} #{$?.inspect}"
false
end
end
def extract_file(filename)
puts case ext = File.extname(filename)
when '.tgz' then `tar xzf #{filename}`
when '.zip' then `unzip #{filename}`
else
STDERR.puts "Cannot extract #{filename}. Unknown extension: #{ext}"
return false
end
# need error handling and messaging
if $?.success?
true
else
STDERR.puts "Failed extracting #{filename} code #{$?.class} #{$?.inspect}"
false
end
end
# check for already downloaded books
ROOT = Dir.pwd
TAR_FILES = Dir[File.join(ROOT, "**", "*.tgz")]
def check_for_duplicates(prag_ref)
case TAR_FILES.count {|file| File.basename(file) == tar_file(prag_ref) }
when 1
# do nothing. expected
when (2..Float::INFINITY)
expected_file = File.join(ROOT, prag_ref, tar_file(prag_ref))
matches = TAR_FILES.select {|file| File.basename(file) == File.basename(expected_file) }
puts "#{prag_ref}: #{matches - [expected_file]}"
else
puts "That's odd, none found #{prag_ref}"
end
end
puts
books.each do |prag_ref, details|
in_dir(prag_ref) do
print '.'
if extract_code?
file = tar_file(prag_ref)
if download_code?(file)
download_link = "http://media.pragprog.com/titles/#{prag_ref}/code/#{file}"
next unless download_code(download_link)
end
next unless extract_file(file)
`git add code && git commit -m "Adding code #{prag_ref}: #{details[:name]}"`.strip
# handle artifacts
# handle different releases
end
check_for_duplicates(prag_ref)
end
end
puts
{
'SecretsOfTheJavascriptNinja' => 'http://www.manning.com/resig/ninja-code.zip',
'Rails4InAction' => 'https://github.com/steveklabnik/ticketee/archive/master.zip',
'Rails3InAction' => 'http://www.manning.com/katz/ticketee-book.zip',
# 'dpir' => { name: "Design Patterns in Ruby", source_code: "http://designpatternsinruby.com/extras/dpir_code.zip" },
# 'practical_ruby_projects' => { name: "Practical Ruby Projects. Ideas for the Eclectic Programmer", source_code: "http://www.apress.com/downloadable/download/sample/sample_id/564/", filename: '9781590599112.zip'},
}.each do |ref, zip_link|
in_dir(ref) do
print '.'
file = File.basename(zip_link)
if download_code?(file)
next unless download_code(zip_link)
end
next unless extract_file(file)
`git add . && git commit -m "Adding code #{ref}: #{file}"`.strip
# handle artifacts
# handle different releases
end
end