tiny_site 0.1.1

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.
Files changed (3) hide show
  1. data/lib/tiny_site.rb +119 -0
  2. data/lib/tiny_site/version.rb +3 -0
  3. metadata +100 -0
@@ -0,0 +1,119 @@
1
+ require 'open-uri'
2
+ require 'RedCloth'
3
+ require 'yaml'
4
+ require 'haml'
5
+
6
+ class TextileParts
7
+ def self.parse(tp, image_path='')
8
+ vars, *parts = tp.split(/^\+\+\+\+|\+\+\+\+$/)
9
+
10
+ vars = YAML.load(vars) || {}
11
+ parts = Hash[*parts]
12
+ parts.each{|k,v| parts[k] = textilize(v,image_path)}
13
+
14
+ return vars, parts
15
+ end
16
+ def self.textilize(string, image_path)
17
+ string.gsub!(%r{!([\w\d\-\._]+)!}){ |a| "!#{image_path}/#{$1}!" }
18
+
19
+ RedCloth.new(string).to_html
20
+ end
21
+ end
22
+
23
+ class CachedHttpFile
24
+ def initialize(url, expires_in=3600)
25
+ @url, @expires_in = url, expires_in
26
+ end
27
+
28
+ def fetch
29
+ puts "fetching #{@url}"
30
+ @body = open(@url).read
31
+ store
32
+ return 200, @body
33
+ rescue OpenURI::HTTPError => error
34
+ puts "OpenURI::HTTPError: #{error.message}"
35
+ return error.message.to_i, nil
36
+ end
37
+
38
+ def cached?
39
+ self.class.files[@url] && self.class.files[@url][:expires_at] > Time.now
40
+ end
41
+ def cached
42
+ return 200, self.class.files[@url][:content]
43
+ end
44
+
45
+ def store
46
+ puts "storing body of #{@url}"
47
+ self.class.files[@url] = {:content => @body, :expires_at => Time.now + @expires_in}
48
+ end
49
+
50
+ def get
51
+ (cached? && cached) || fetch
52
+ end
53
+
54
+ class << self
55
+ def files
56
+ @files ||= {}
57
+ end
58
+ def get(url, expires_in=3600)
59
+ (new url, expires_in).get
60
+ end
61
+ def bust
62
+ puts 'busting cache'
63
+ @files = {}
64
+ end
65
+ end
66
+ end
67
+
68
+ class TinySite
69
+ def initialize(opts)
70
+ @file_path = opts[:file_path]
71
+ @image_path = opts[:image_path] || File.join(@file_path, 'images')
72
+ @cache_buster = opts[:cache_buster] || 'bust'
73
+ end
74
+
75
+ def remote_file_url_for(filename)
76
+ File.join @file_path, "#{filename}.textile"
77
+ end
78
+
79
+ def render
80
+ global_file_fetch_tread = Thread.new{
81
+ _, @global_file = CachedHttpFile.get remote_file_url_for('__global') } # get __global in background
82
+ @status, page_file = CachedHttpFile.get remote_file_url_for(@path)
83
+ _, page_file = CachedHttpFile.get remote_file_url_for(@status) if @status != 200
84
+ global_file_fetch_tread.join
85
+
86
+ global_vars, global_parts = TextileParts.parse @global_file, @image_path
87
+ page_vars, page_parts = TextileParts.parse page_file, @image_path
88
+
89
+ render_layout :global_vars => global_vars, :global_parts => global_parts,
90
+ :page_vars => page_vars, :page_parts => page_parts
91
+ end
92
+
93
+ def render_layout(params)
94
+ layout = params[:page_vars][:layout] || params[:global_vars][:layout] || 'layout'
95
+
96
+ puts "rendering layout '#{layout}'"
97
+ haml = Haml::Engine.new File.open("#{layout}.haml").read, :format => :html5
98
+ haml.render Object.new, params
99
+ end
100
+
101
+ def caching_header
102
+ return { 'Cache-Control' => 'public, max-age=3600' } unless @query_string == @cache_buster
103
+
104
+ CachedHttpFile.bust and return { 'Cache-Control' => 'no-cache' }
105
+ end
106
+
107
+ def call(env)
108
+ @path, @query_string = env['PATH_INFO'], env['QUERY_STRING']
109
+ @path = '/index' if @path == '/'
110
+
111
+ return [301, {'Location' => @path}, ''] if @path.gsub!(/\/$/,'')
112
+
113
+ body = render # render the body first to set @status
114
+ [@status, caching_header, body]
115
+ rescue => e
116
+ puts "#{e.class}: #{e.message} #{e.backtrace}"
117
+ [500, {}, 'Sorry, but something went wrong']
118
+ end
119
+ end
@@ -0,0 +1,3 @@
1
+ class TinySite
2
+ VERSION = "0.1.1"
3
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tiny_site
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.1
6
+ platform: ruby
7
+ authors:
8
+ - Niko Dittmann
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-02-27 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rack
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: RedCloth
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: haml
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ description: A static small site engine with Heroku and DropBox in mind
61
+ email: mail+git@niko-dittmann.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files: []
67
+
68
+ files:
69
+ - lib/tiny_site/version.rb
70
+ - lib/tiny_site.rb
71
+ has_rdoc: true
72
+ homepage: http://github.com/niko/tiny_site
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project: "[none]"
95
+ rubygems_version: 1.5.0
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: A static small site engine with Heroku and DropBox in mind
99
+ test_files: []
100
+