wbzyl-seminarium 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.markdown +42 -0
  2. data/Rakefile +40 -0
  3. data/TODO +8 -0
  4. data/config.ru +2 -0
  5. data/lib/public/doc/neukirchen07introducingrack.pdf +0 -0
  6. data/lib/public/favicon.ico +0 -0
  7. data/lib/public/images/emurphy.gif +0 -0
  8. data/lib/public/images/openquote.gif +0 -0
  9. data/lib/public/images/rack-1.png +0 -0
  10. data/lib/public/images/rack-1.svg +329 -0
  11. data/lib/public/images/rack-2.png +0 -0
  12. data/lib/public/images/rack-2.svg +419 -0
  13. data/lib/public/images/rack-logo.png +0 -0
  14. data/lib/public/images/rack-logo.svg +113 -0
  15. data/lib/public/javascripts/lang-css.js +2 -0
  16. data/lib/public/javascripts/lang-hs.js +2 -0
  17. data/lib/public/javascripts/lang-lisp.js +3 -0
  18. data/lib/public/javascripts/lang-lua.js +2 -0
  19. data/lib/public/javascripts/lang-ml.js +2 -0
  20. data/lib/public/javascripts/lang-proto.js +1 -0
  21. data/lib/public/javascripts/lang-sql.js +2 -0
  22. data/lib/public/javascripts/lang-vb.js +2 -0
  23. data/lib/public/javascripts/lang-wiki.js +1 -0
  24. data/lib/public/javascripts/prettify.js +31 -0
  25. data/lib/public/stylesheets/application.css +67 -0
  26. data/lib/public/stylesheets/coderay.css +124 -0
  27. data/lib/public/stylesheets/prettify.css +44 -0
  28. data/lib/public/stylesheets/projection.css +127 -0
  29. data/lib/seminarium.rb +28 -0
  30. data/lib/seminarium/info.rb +14 -0
  31. data/lib/seminarium/referaty.rb +16 -0
  32. data/lib/views/index.rdiscount +8 -0
  33. data/lib/views/info.rdiscount +14 -0
  34. data/lib/views/modular-applications-www.erb +451 -0
  35. data/lib/views/presentations-list.erb +3 -0
  36. data/lib/views/slides.erb +33 -0
  37. data/lib/views/styl-naukowy.rdiscount +55 -0
  38. metadata +149 -0
data/lib/seminarium.rb ADDED
@@ -0,0 +1,28 @@
1
+ $KCODE = 'UTF8'
2
+ require 'jcode'
3
+
4
+ gem 'wbzyl-sinatra-static-assets'
5
+ require 'sinatra/static_assets'
6
+ gem 'wbzyl-sinatra-rdiscount'
7
+ require 'sinatra/rdiscount'
8
+
9
+ require 'seminarium/referaty'
10
+ require 'seminarium/info'
11
+
12
+ module Seminarium
13
+ class Info < Sinatra::Base
14
+ set :app_file, __FILE__
15
+ set :static, true
16
+
17
+ set :logging, true
18
+ end
19
+ end
20
+
21
+ module Seminarium
22
+ class Referaty < Sinatra::Base
23
+ set :app_file, __FILE__
24
+ set :static, true
25
+
26
+ set :logging, true
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ require 'sinatra/base'
2
+
3
+ module Seminarium
4
+ class Info < Sinatra::Base
5
+ helpers Sinatra::UrlForHelper
6
+ helpers Sinatra::StaticAssets
7
+
8
+ helpers Sinatra::RDiscount
9
+
10
+ get '/:title' do
11
+ rdiscount :"#{params[:title]}", :layout => :info
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ require 'sinatra/base'
2
+
3
+ module Seminarium
4
+ class Referaty < Sinatra::Base
5
+ helpers Sinatra::UrlForHelper
6
+ helpers Sinatra::StaticAssets
7
+
8
+ #get '/' do
9
+ # erb :"presentations-list", :layout => :layout
10
+ #end
11
+
12
+ get '/:title' do
13
+ erb :"#{params[:title]}", :layout => :slides
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ # Indeks
2
+
3
+ 1. [Kompozycja artykułu, prezentacji, pracy licencjackiej,
4
+ magisterskiej](/styl-naukowy)
5
+
6
+ ## Prezentacje
7
+
8
+ 1. [Modularne aplikacje WWW](/referaty/modular-applications-www)
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
5
+ <%= stylesheet_link_tag "/stylesheets/application.css" %>
6
+ <title><%= @title || "Seminarium 2009/2010" %></title>
7
+ </head>
8
+
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,451 @@
1
+ <div class="slide"><!--<h4 class="title">Modułowe aplikacje WWW</h4>-->
2
+ <div class="slidecontent">
3
+ <% "MODULARNE APLIKACJE WWW ".each_char do |c| %>
4
+ <div class="rect" style="background-color: <%= sprintf("#%.6x;", rand(0xffffff)) %>"><%= c %></div>
5
+ <% end %>
6
+ </div>
7
+ </div>
8
+
9
+ <div class="slide"><h4>Jak budujemy modularne aplikacje WWW?</h4>
10
+ <div class="slidecontent">
11
+ <p><%= image_tag "/images/rack-logo.png", :class => "right", :alt => "rack logo" %>
12
+ Zaczynamy od postawienia stałej konstrukcji nośnej: stojaka
13
+ (ang. <i>rack</i>). Następnie wstawiamy do stojaka
14
+ wymienialne moduły, które zestawiamy według potrzeb, na przykład:
15
+ </p>
16
+ <ul>
17
+ <li>moduły do obsługi różnych typów szablonów: Erb, Markdown</li>
18
+ <li>moduł uaktywniający buforowanie HTTP:
19
+ freshness (Expires, Cache-Control),
20
+ walidacja (Last-Modified, ETag)</li>
21
+ <li>moduły do obsługi baz danych: ActiveRecord, Datamapper</li>
22
+ <li>moduł i18n</li>
23
+ <li>...inne aplikacje modularne</li>
24
+ </ul>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="slide"><h4>Czym są moduły, które wstawiamy do stojaka?</h4>
29
+ <div class="slidecontent">
30
+ <p><a href="http://chneukirchen.org/blog/">Christian Neukirchen</a>,
31
+ <i>Rack: a Ruby Webserver Interface</i></p>
32
+
33
+ <blockquote>
34
+ <p>Dabbling in my own web framework experiments, I noticed that
35
+ there is a lot of code duplication among frameworks since they
36
+ essentially all do the same things. And still, every Ruby web
37
+ framework developer is writing his own handlers for every
38
+ webserver he wants to use. Hopefully, the framework users are
39
+ satisfied with that choice.</p>
40
+ </blockquote>
41
+
42
+ <p class="def">
43
+ Nieformalnie, <b>modułem/aplikacją Rack</b>
44
+ jest <i><b>obiekt</b></i> odpowiadający na wywołanie <b>#call</b>
45
+ z haszem jako jedynym argumentem i zwracającym tablicę
46
+ trzech elementów: <b>status</b>, <b>headers</b> i <b>body</b>.
47
+ </p>
48
+
49
+ <!--
50
+ <p>Artykuł Christiana Neukirchena z opisem implementacji powyższej specyfikacji:
51
+ <i><a href="/doc/neukirchen07introducingrack.pdf">Introducing Rack</a></i>.</p>
52
+ -->
53
+
54
+ </div>
55
+ </div>
56
+
57
+ <div class="slide"><h4>Funkcja modułem Rack</h4>
58
+ <div class="slidecontent">
59
+
60
+ <pre><code>:::ruby
61
+ # app.rb
62
+ require 'rubygems'
63
+ require 'rack'
64
+
65
+ App = lambda do |env|
66
+ [
67
+ 200, # status
68
+ {"Content-Type" => "text/html; charset=utf-8"}, # headers
69
+ [ "hello world" ] # body
70
+ ]
71
+ end
72
+
73
+ Rack::Handler::Thin.run App, :Port => 9292
74
+ </code></pre>
75
+ <p>
76
+ Tę aplikację uruchamiamy po prostu tak
77
+ (bez wstawiania do stojaka):</p>
78
+ <pre><code>ruby app.rb
79
+ </code></pre>
80
+
81
+ </div>
82
+ </div>
83
+
84
+
85
+ <div class="slide"><h4>Czym jest argument *env*?</h4>
86
+ <div class="slidecontent">
87
+
88
+ <p>Argument <i>env</i> jest haszem, wyglądającym mniej więcej tak:</p>
89
+
90
+ <pre><code>:::ruby
91
+ {
92
+ "HTTP_ACCEPT" => "*/*",
93
+ "HTTP_HOST" => "inf.univ.gda.pl",
94
+ "HTTP_PRAGMA" => "no-cache",
95
+ "HTTP_USER_AGENT" => "curl/7.12.2 ..."
96
+ "PATH_INFO" => "/",
97
+ "QUERY_STRING" => "",
98
+ "REMOTE_ADDR" => "127.0.0.1",
99
+ "REMOTE_HOST" => "127.0.0.1",
100
+ "REQUEST_METHOD" => "GET"
101
+ "REQUEST_PATH" => "/",
102
+ "REQUEST_URI" => "http://inf.univ.gda.pl/",
103
+ "SCRIPT_NAME" => "",
104
+ "SERVER_PORT" => "80",
105
+ "SERVER_PROTOCOL" => "HTTP/1.1",
106
+ }
107
+ </code></pre>
108
+
109
+ </div>
110
+ </div>
111
+
112
+
113
+
114
+ <div class="slide"><h4>Instancja klasy modułem Rack</h4>
115
+ <div class="slidecontent">
116
+
117
+ <pre><code>:::ruby
118
+ # helloworld.rb
119
+ class HelloWorld
120
+ def call(env)
121
+ [200, {"Content-Type" => "text/html"}, ["hello world"]]
122
+ end
123
+ end
124
+ </code></pre>
125
+
126
+ <p>Tę klasę wstawiamy do stojaka (jako jedyny moduł):</p>
127
+ <pre><code>:::ruby
128
+ # app2.ru
129
+ require 'helloworld'
130
+ run HelloWorld.new
131
+ </code></pre>
132
+ <p>i uruchamiamy wpisując w wierszu poleceń:</p>
133
+ <pre><code>rackup -s thin -p 9292 app2.ru
134
+ </code></pre>
135
+
136
+ </div>
137
+ </div>
138
+
139
+ <div class="slide"><h4>Filtry, czyli Rack Middleware</h4>
140
+ <div class="slidecontent">
141
+ <p class="quote">
142
+ Between the server and the framework, Rack can be customized to your
143
+ applications needs using middleware, for example:
144
+ </p>
145
+ <ul>
146
+ <li><b>Rack::CommonLogger</b>, for creating Apache-style logfiles.</li>
147
+ <li><b>Rack::ShowExceptions</b>, for catching unhandled exceptions and
148
+ presenting them in a nice and helpful way with clickable backtrace.</li>
149
+ <li><b>Rack::File</b>, for serving static files.</li>
150
+ <li><b>Rack::Static</b> intercepts requests for static
151
+ files (javascript files, images, stylesheets, etc) based on
152
+ the url prefixes passed in the options, and serves them
153
+ using a Rack::File object.</li>
154
+ <li>...and many others!</li>
155
+ </ul>
156
+ </div>
157
+ </div>
158
+
159
+ <div class="slide"><h4>Aplikacja Rack z dołożonym Middleware</h4>
160
+ <div class="slidecontent">
161
+ <%= image_tag "/images/rack-1.png", :alt => "rack: middleware | apps" %>
162
+ </div>
163
+ </div>
164
+
165
+
166
+ <div class="slide"><h4>Jak składamy aplikacje modularne?</h4>
167
+ <div class="slidecontent">
168
+
169
+ <p>Aplikacje składamy tak, jak składamy funkcje:</p>
170
+
171
+ <pre><code>:::ruby
172
+ app = Rack::CommonLogger.new(
173
+ Rack::ShowExceptions.new(
174
+ Rack::Lint.new(MyRackApp.new)))
175
+ </pre></code>
176
+
177
+ <p>Albo tak:</p>
178
+
179
+ <pre><code>:::ruby
180
+ app = MyRackApp.new
181
+ app = Rack::Lint.new(app)
182
+ app = Rack::ShowExceptions.new(app)
183
+ app = Rack::CommonLogger.new(app)
184
+ </pre></code>
185
+
186
+ </div>
187
+ </div>
188
+
189
+ <div class="slide"><h4>albo w postaci „kaskady”...</h4>
190
+ <div class="slidecontent">
191
+ <ul>
192
+ <li><b>Rack::Cascade</b>, tries an request on several apps,
193
+ and returns the first response that is not 404
194
+ (or in a list of configurable status codes)</li>
195
+ <li><i>Aplikację Rack zamieniamy na moduł za pomocą</i></li>
196
+ <li><b>Rack::Builder</b> implements a small DSL to iteratively
197
+ construct Rack applications oraz</li>
198
+ <li><b>Rack::URLMap</b>, to route to multiple applications
199
+ inside the same process</li>
200
+ </ul>
201
+ </div>
202
+ </div>
203
+
204
+ <div class="slide"><h4>Iteracyjne składanie + kaskada aplikacji Rack</h4>
205
+ <div class="slidecontent">
206
+ <%= image_tag "/images/rack-2.png", :alt => "rack: middleware | apps" %>
207
+ </div>
208
+ </div>
209
+
210
+ <div class="slide"><h4>Rack::Builder — składamy middleware z aplikacją</h4>
211
+ <div class="slidecontent">
212
+
213
+ <pre><code>:::ruby
214
+ # rapp.ru
215
+ require 'helloworld'
216
+
217
+ Rapp = Rack::Builder.new do
218
+ use Rack::Lint
219
+ run HelloWorld.new
220
+ end
221
+
222
+ use Rack::CommonLogger
223
+ run Rapp
224
+ </code></pre>
225
+
226
+ <p>Aplikację <i>rapp.ru</i> uruchamiamy tak:</p>
227
+ <pre><code>rackup rapp.ru
228
+ </code></pre>
229
+ <p>Polecenie <code>rackup</code> doda za nas wiersz
230
+ z <i>Rack::Handler</i> oraz bibliotekę
231
+ <i>rubygems</i> i <i>rack</i>.
232
+ </p>
233
+
234
+ </div>
235
+ </div>
236
+
237
+ <div class="slide"><h4>Aplikacje Rack: Pi, Euler...</h4>
238
+ <div class="slidecontent">
239
+ <pre><code>:::ruby
240
+ require 'rack/request' ; require 'rack/response'
241
+ require 'bigdecimal' ; require 'bigdecimal/math'
242
+ include BigMath
243
+ module Rack
244
+ class Pi
245
+ def call(env)
246
+ req = Request.new(env)
247
+ prec = req.GET["prec"].to_i
248
+ res = Response.new
249
+ res.write "&lt;title>PI&lt;/title>"
250
+ res.write "&lt;p>"
251
+ res.write PI(prec + 1).to_s("10F")
252
+ res.write "&lt;/p>"
253
+ res.finish
254
+ end
255
+ end
256
+ end
257
+ </code></pre>
258
+ </div>
259
+ </div>
260
+
261
+ <div class="slide"><h4>Iteracyjnie budujemy aplikację</h4>
262
+ <div class="slidecontent">
263
+
264
+ <pre><code>:::ruby
265
+ # app3.rb
266
+ require 'rack-math' # gem z aplikacjami Rack:Euler, Rack:Pi...
267
+ App3 = Rack::Builder.new do
268
+ map '/pi' do
269
+ run Rack::Pi.new
270
+ end
271
+ map '/euler' do
272
+ run Rack::Euler.new
273
+ end
274
+ end
275
+ </code></pre>
276
+
277
+ <p>Umieszczamy aplikację w stojaku, który uruchamiamy za pomocą
278
+ <code>rackup</code>:
279
+ </p>
280
+ <pre><code>:::ruby
281
+ # app3.ru
282
+ require 'app3'
283
+ run App3
284
+ </code></pre>
285
+
286
+ </div>
287
+ </div>
288
+
289
+
290
+ <div class="slide"><h4>...kontynuuuuacja poprzedniego slajdu</h4>
291
+ <div class="slidecontent">
292
+
293
+ <p>Włączamy jeszcze jedną aplikację z gemu <i>Rack</i>:
294
+ <pre><code>:::ruby
295
+ # app4.rb
296
+ require 'rack/lobster' ; require 'app3'
297
+ App4 = Rack::Builder.new do
298
+ map '/math' do
299
+ run App3
300
+ end
301
+ map '/lobster' do
302
+ run Rack::Lobster.new
303
+ end
304
+ end
305
+ </code></pre>
306
+
307
+ <p>Uruchamiamy aplikację <i>app4.ru</i>:
308
+ <pre><code>:::ruby
309
+ require 'app4'
310
+ use Rack::CommonLogger
311
+ run App4
312
+ </code></pre>
313
+
314
+ </div>
315
+ </div>
316
+
317
+
318
+ <div class="slide"><h4>Modułowe aplikacje Sinatry: Sinatra:Pi, Sinatra:Euler</h4>
319
+ <div class="slidecontent">
320
+
321
+ <p>Korzystamy z <b>layoutu</b> i <b>szablonów</b>. Kopiujemy zmienne do szablonów.</p>
322
+
323
+ <pre><code>:::ruby
324
+ # sinatra-math/pi.rb
325
+ require 'bigdecimal'
326
+ require 'bigdecimal/math'
327
+ include BigMath
328
+
329
+ module Sinatra
330
+ class Pi < Sinatra::Base
331
+ get '/?' do
332
+ prec = params[:prec].to_i
333
+ @pi = PI(prec + 1).to_s("10F")
334
+ @cname = 'PI'
335
+ erb :pi
336
+ end
337
+ end
338
+ end
339
+ </code></pre>
340
+
341
+ </div>
342
+ </div>
343
+
344
+ <div class="slide"><h4>...kontunuuuuacja poprzedniego slajdu</h4>
345
+ <div class="slidecontent">
346
+
347
+ <p>Poniższą aplikację urozmaicimy homarem:</p>
348
+ <pre><code>:::ruby
349
+ # app5.rb
350
+ require 'sinatra/base' ; require 'sinatra-math' ; require 'rack/lobster'
351
+ SinatraApp5 = Rack::Builder.new do
352
+ map '/' do
353
+ run Sinatra::Pi.new
354
+ end
355
+ map '/lobster' do
356
+ run Rack::Lobster.new
357
+ end
358
+ end
359
+ </code></pre>
360
+ <p>i uruchomimy ją korzystając via prosty plik:</p>
361
+ <pre><code>:::ruby
362
+ # app5.ru
363
+ require 'app5'
364
+ run SinatraApp5
365
+ </code></pre>
366
+
367
+ </div>
368
+ </div>
369
+
370
+
371
+ <div class="slide"><h4>Modułowe aplikacje Rails 3</h4>
372
+ <div class="slidecontent">
373
+
374
+ <p>
375
+ Yehuda Katz,
376
+ <a href="http://en.oreilly.com/rails2009/public/schedule/detail/7785">The
377
+ Russian Doll Pattern: Mountable apps in Rails 3</a>
378
+ </p>
379
+ <blockquote cite="http://en.oreilly.com/rails2009/public/schedule/detail/7785">
380
+ <p>One of the hottest new features in Rails 3 is the ability to
381
+ embed a Rails application in another Rails application. This
382
+ allows the development of components that range from user
383
+ authentication to a fully featured forum. These components can
384
+ then be distributed as gems and fully integrated with another
385
+ application. In fact, user private messaging could be a stand
386
+ alone app, which is then mounted into a forum app, and finally
387
+ mounted into your own custom app.</p>
388
+ </blockquote>
389
+
390
+ </div>
391
+ </div>
392
+
393
+
394
+ <div class="slide"><h4>Prawa Murphy’ego (1918–1990)</h4>
395
+ <div class="slidecontent">
396
+ <blockquote>
397
+ <img src="/images/emurphy.gif" alt="E. A. Murphy">
398
+ <p>Nic nie jest tak łatwe, jak wygląda.</p>
399
+ </blockquote>
400
+ </div>
401
+ </div>
402
+
403
+ <div class="slide"><h4>Railsconf 2009 Recap</h4>
404
+ <div class="slidecontent">
405
+ <blockquote cite="http://blog.zerosum.org/?q=node/66">
406
+ <p>Interestingly, I really didn’t care for many of the (very
407
+ rough) ideas expressed in Yehuda’s mountable Rails apps (Rails
408
+ 3) session — in particular I really had no clue why they kept
409
+ comparing Rails (a framework) to Drupal (a CMS). But, that said,
410
+ the talk did do a great job stimulating discussion about
411
+ alternative approaches in „CabooseConf” — apparently just a
412
+ small room with, uh, tables and stuff — between myself, Bryan,
413
+ Josh, Ted and others. For this reason it definitely belongs in
414
+ my favorite sessions list.</p>
415
+ </blockquote>
416
+ </div>
417
+ </div>
418
+
419
+ <div class="slide"><h4>...more Railsconf 2008</h4>
420
+ <div class="slidecontent">
421
+
422
+ <blockquote>
423
+ <p>Każde rozwiązanie ujawnia nowe problemy.</p>
424
+ <p class="author">— Edward A. Murphy</p>
425
+ </blockquote>
426
+
427
+ <blockquote cite="http://blog.zerosum.org/?q=node/66">
428
+ <p>[mountable app slices] are a challenging problem, and there
429
+ are a lot of issues in terms of sharing application state,
430
+ resolving cross-app dependencies, and so on. I hope that we’ll
431
+ have an elegant solution to this soon; but I suspect that the
432
+ real answer may be in making component-sized micro-apps easier
433
+ to mount and integrate rather than taking an „app slices” or
434
+ engines approach (if the latter case prevails, the Radiant
435
+ extensions system has some stuff we can learn from).</p>
436
+ </blockquote>
437
+
438
+ </div>
439
+ </div>
440
+
441
+ <!--
442
+
443
+ # RAILS_ROOT/config.ru
444
+
445
+ require "config/environment"
446
+
447
+ use Rails::Rack::LogTailer
448
+ use Rails::Rack::Static
449
+ run ActionController::Dispatcher.new
450
+
451
+ -->