toto 0.2.8 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.8
1
+ 0.3.0
data/lib/toto.rb CHANGED
@@ -3,6 +3,7 @@ require 'time'
3
3
  require 'erb'
4
4
  require 'rack'
5
5
  require 'digest'
6
+ require 'open-uri'
6
7
 
7
8
  require 'rdiscount'
8
9
  require 'builder'
@@ -28,10 +29,22 @@ module Toto
28
29
 
29
30
  module Template
30
31
  def to_html page, &blk
31
- path = (page == :layout ? Paths[:templates] : Paths[:pages])
32
+ path = ([:layout, :repo].include?(page) ? Paths[:templates] : Paths[:pages])
32
33
  ERB.new(File.read("#{path}/#{page}.rhtml")).result(binding)
33
34
  end
34
35
 
36
+ def markdown text
37
+ if (options = @config[:markdown])
38
+ Markdown.new(text.to_s.strip, *(options.eql?(true) ? [] : options)).to_html
39
+ else
40
+ text.strip
41
+ end
42
+ end
43
+
44
+ def method_missing m, *args, &blk
45
+ self.keys.include?(m) ? self[m] : super
46
+ end
47
+
35
48
  def self.included obj
36
49
  obj.class_eval do
37
50
  define_method(obj.to_s.split('::').last.downcase) { self }
@@ -87,21 +100,27 @@ module Toto
87
100
 
88
101
  def go route, type = :html
89
102
  route << self./ if route.empty?
90
- type, path = type.to_sym, route.join('/')
103
+ type, path = type =~ /html|xml|json/ ? type.to_sym : :html, route.join('/')
104
+ context = lambda do |data, page|
105
+ Context.new(data, @config, path).render(page, type)
106
+ end
91
107
 
92
108
  body, status = if Context.new.respond_to?(:"to_#{type}")
93
109
  if route.first =~ /\d{4}/
94
110
  case route.size
95
111
  when 1..3
96
- Context.new(archives(route * '-'), @config, path).render(:archives, type)
112
+ context[archives(route * '-'), :archives]
97
113
  when 4
98
- Context.new(article(route), @config, path).render(:article, type)
114
+ context[article(route), :article]
99
115
  else http 400
100
116
  end
101
- elsif respond_to?(route = route.first.to_sym)
102
- Context.new(send(route, type), @config, path).render(route, type)
117
+ elsif respond_to?(path)
118
+ context[send(path, type), path.to_sym]
119
+ elsif (repo = @config[:github][:repos].grep(/#{path}/).first) &&
120
+ !@config[:github][:user].empty?
121
+ context[Repo.new(repo, @config), :repo]
103
122
  else
104
- Context.new({}, @config, path).render(route.to_sym, type)
123
+ context[{}, path.to_sym]
105
124
  end
106
125
  else
107
126
  http 400
@@ -161,6 +180,24 @@ module Toto
161
180
  end
162
181
  end
163
182
 
183
+ class Repo < Hash
184
+ include Template
185
+
186
+ README = "http://github.com/%s/%s/raw/master/README.%s"
187
+
188
+ def initialize name, config
189
+ self[:name], @config = name, config
190
+ end
191
+
192
+ def readme
193
+ markdown open(README %
194
+ [@config[:github][:user], self[:name], @config[:github][:ext]]).read
195
+ rescue Timeout::Error, OpenURI::HTTPError => e
196
+ "This page isn't available."
197
+ end
198
+ alias :content readme
199
+ end
200
+
164
201
  class Archives < Array
165
202
  include Template
166
203
 
@@ -233,19 +270,6 @@ module Toto
233
270
 
234
271
  alias :to_s to_html
235
272
 
236
- def method_missing m, *args, &blk
237
- self.keys.include?(m) ? self[m] : super
238
- end
239
-
240
- private
241
-
242
- def markdown text
243
- if (options = @config[:markdown])
244
- Markdown.new(text.to_s.strip, *(options.eql?(true) ? [] : options)).to_html
245
- else
246
- text.strip
247
- end
248
- end
249
273
  end
250
274
 
251
275
  class Config < Hash
@@ -259,14 +283,21 @@ module Toto
259
283
  :disqus => false, # disqus name
260
284
  :summary => {:max => 150, :delim => /~\n/}, # length of summary and delimiter
261
285
  :ext => 'txt', # extension for articles
262
- :cache => 28800 # cache duration (seconds)
286
+ :cache => 28800, # cache duration (seconds)
287
+ :github => {:user => "", :repos => [], :ext => 'md'}# Github username and list of repos
263
288
  }
264
289
  def initialize obj
265
290
  self.update Defaults
266
291
  self.update obj
267
292
  end
268
293
 
269
- alias set :[]=
294
+ def set key, val
295
+ if val.is_a? Hash
296
+ self[key].update val
297
+ else
298
+ self[key] = val
299
+ end
300
+ end
270
301
 
271
302
  def [] key, *args
272
303
  val = super(key)
@@ -0,0 +1 @@
1
+ <%= readme %>
data/test/toto_test.rb CHANGED
@@ -79,6 +79,30 @@ context Toto do
79
79
  asserts("summary shouldn't be empty") { topic.body }.includes_html("summary" => /.{10,}/)
80
80
  end
81
81
 
82
+ context "GET to a repo name" do
83
+ setup do
84
+ class Toto::Repo
85
+ def readme() "#{self[:name]}'s README" end
86
+ end
87
+ end
88
+
89
+ context "when the repo is in the :repos array" do
90
+ setup do
91
+ @config[:github] = {:user => "cloudhead", :repos => ['the-repo']}
92
+ @toto.get('/the-repo')
93
+ end
94
+ should("return the-repo's README") { topic.body }.includes("the-repo's README")
95
+ end
96
+
97
+ context "when the repo is not in the :repos array" do
98
+ setup do
99
+ @config[:github] = {:user => "cloudhead", :repos => []}
100
+ @toto.get('/the-repo')
101
+ end
102
+ should("return a 404") { topic.status }.equals 404
103
+ end
104
+ end
105
+
82
106
  context "creating an article" do
83
107
  setup do
84
108
  @config[:markdown] = true
@@ -145,6 +169,17 @@ context Toto do
145
169
  end
146
170
  end
147
171
  end
172
+
173
+ context "using Config#set with a hash" do
174
+ setup do
175
+ conf = Toto::Config.new({})
176
+ conf.set(:summary, {:delim => /%/})
177
+ conf
178
+ end
179
+
180
+ should("set summary[:delim] to /%/") { topic[:summary][:delim].source }.equals "%"
181
+ should("leave the :max intact") { topic[:summary][:max] }.equals 150
182
+ end
148
183
  end
149
184
 
150
185
 
data/toto.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{toto}
8
- s.version = "0.2.8"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["cloudhead"]
12
- s.date = %q{2010-02-06}
12
+ s.date = %q{2010-02-08}
13
13
  s.description = %q{the tiniest blog-engine in Oz.}
14
14
  s.email = %q{self@cloudhead.net}
15
15
  s.extra_rdoc_files = [
@@ -37,6 +37,7 @@ Gem::Specification.new do |s|
37
37
  "test/templates/feed.builder",
38
38
  "test/templates/index.rhtml",
39
39
  "test/templates/layout.rhtml",
40
+ "test/templates/repo.rhtml",
40
41
  "test/test_helper.rb",
41
42
  "test/toto_test.rb",
42
43
  "toto.gemspec"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cloudhead
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-06 00:00:00 -05:00
12
+ date: 2010-02-08 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -82,6 +82,7 @@ files:
82
82
  - test/templates/feed.builder
83
83
  - test/templates/index.rhtml
84
84
  - test/templates/layout.rhtml
85
+ - test/templates/repo.rhtml
85
86
  - test/test_helper.rb
86
87
  - test/toto_test.rb
87
88
  - toto.gemspec