camping 1.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.
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #$:.unshift File.dirname(__FILE__) + "/../../lib"
4
+ require 'rubygems'
5
+ require 'camping'
6
+
7
+ module Camping::Models
8
+ class Post < Base; belongs_to :user; end
9
+ class Comment < Base; belongs_to :user; end
10
+ class User < Base; end
11
+ end
12
+
13
+ module Camping::Controllers
14
+ class Index < R '/'
15
+ def get
16
+ @posts = Post.find :all
17
+ render :index
18
+ end
19
+ end
20
+
21
+ class Add
22
+ def get
23
+ if cookies.user_id
24
+ @session = User.find cookies.user_id
25
+ end
26
+ render :add
27
+ end
28
+ def post
29
+ post = Post.create :title => input.post_title, :body => input.post_body
30
+ redirect View, post
31
+ end
32
+ end
33
+
34
+ class Info
35
+ def get
36
+ pre cookies.inspect
37
+ end
38
+ end
39
+
40
+ class View < R '/view/(\d+)'
41
+ def get post_id
42
+ @post = Post.find post_id
43
+ @comments = Comment.find :all, :conditions => ['post_id = ?', post_id]
44
+ render :view
45
+ end
46
+ end
47
+
48
+ class Edit < R '/edit/(\d+)', '/edit'
49
+ def get post_id
50
+ if cookies.user_id
51
+ @session = User.find cookies.user_id
52
+ end
53
+ @post = Post.find post_id
54
+ render :edit
55
+ end
56
+
57
+ def post
58
+ @post = Post.find input.post_id
59
+ @post.update_attributes :title => input.post_title, :body => input.post_body
60
+ redirect View, @post
61
+ end
62
+ end
63
+
64
+ class Comment
65
+ def post
66
+ Comment.create(:username => input.post_username,
67
+ :body => input.post_body, :post_id => input.post_id)
68
+ redirect View, input.post_id
69
+ end
70
+ end
71
+
72
+ class Login
73
+ def post
74
+ @user = User.find :first, :conditions => ['username = ? AND password = ?', input.username, input.password]
75
+
76
+ if @user
77
+ @login = 'login success !'
78
+ cookies.user_id = @user.id
79
+ else
80
+ @login = 'wrong user name or password'
81
+ end
82
+ render :login
83
+ end
84
+ end
85
+
86
+ class Logout
87
+ def get
88
+ cookies.user_id = nil
89
+ render :logout
90
+ end
91
+ end
92
+
93
+ class Style < R '/styles.css', '/view/styles.css'
94
+ def get
95
+ @headers["Content-Type"] = "text/css; charset=utf-8"
96
+ @body = File.read('styles.css')
97
+ end
98
+ end
99
+ end
100
+
101
+ module Camping::Views
102
+
103
+ def layout
104
+ html do
105
+ head do
106
+ title 'blog'
107
+ link :rel => 'stylesheet', :type => 'text/css',
108
+ :href => 'styles.css', :media => 'screen'
109
+ end
110
+ body do
111
+ h1.header { a 'blog', :href => '/' }
112
+ div.content do
113
+ self << yield
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ def index
120
+ if @posts.empty?
121
+ p 'No posts found.'
122
+ p { a 'Add', :href => '/add' }
123
+ else
124
+ for post in @posts
125
+ _post(post)
126
+ end
127
+ end
128
+ end
129
+
130
+ def login
131
+ p { b @login }
132
+ p { a 'Continue', :href => '/add' }
133
+ end
134
+
135
+ def logout
136
+ p "You have been logged out."
137
+ p { a 'Continue', :href => '/' }
138
+ end
139
+
140
+ def add
141
+ if @session
142
+ _form(post, :action => '/add')
143
+ else
144
+ _login
145
+ end
146
+ end
147
+
148
+ def edit
149
+ if @session
150
+ _form(post, :action => '/edit')
151
+ else
152
+ _login
153
+ end
154
+ end
155
+
156
+ def view
157
+ _post(post)
158
+
159
+ p "Comment for this post:"
160
+ for c in @comments
161
+ h1 c.username
162
+ p c.body
163
+ end
164
+
165
+ form :action => '/comment', :method => 'post' do
166
+ label 'Name', :for => 'post_username'; br
167
+ input :name => 'post_username', :type => 'text'; br
168
+ label 'Comment', :for => 'post_body'; br
169
+ textarea :name => 'post_body' do; end; br
170
+ input :type => 'hidden', :name => 'post_id', :value => post.id
171
+ input :type => 'submit'
172
+ end
173
+ end
174
+
175
+ # partials
176
+ def _login
177
+ form :action => '/login', :method => 'post' do
178
+ label 'Username', :for => 'username'; br
179
+ input :name => 'username', :type => 'text'; br
180
+
181
+ label 'Password', :for => 'password'; br
182
+ input :name => 'password', :type => 'text'; br
183
+
184
+ input :type => 'submit', :name => 'login', :value => 'Login'
185
+ end
186
+ end
187
+
188
+ def _post(post)
189
+ h1 post.title
190
+ p post.body
191
+ p do
192
+ a "Edit", :href => "/edit/#{post.id}"
193
+ a "View", :href => "/view/#{post.id}"
194
+ end
195
+ end
196
+
197
+ def _form(post, opts)
198
+ p do
199
+ text "You are logged in as #{@session.username} | "
200
+ a 'Logout', :href => '/logout'
201
+ end
202
+ form({:method => 'post'}.merge(opts)) do
203
+ label 'Title', :for => 'post_title'; br
204
+ input :name => 'post_title', :type => 'text',
205
+ :value => post.title; br
206
+
207
+ label 'Body', :for => 'post_body'; br
208
+ textarea post.body, :name => 'post_body'; br
209
+
210
+ input :type => 'hidden', :name => 'post_id', :value => post.id
211
+ input :type => 'submit'
212
+ end
213
+ end
214
+ end
215
+
216
+ if __FILE__ == $0
217
+ Camping::Models::Base.establish_connection :adapter => 'sqlite3', :database => 'blog3.db'
218
+ Camping::Models::Base.logger = Logger.new('camping.log')
219
+ Camping.run
220
+ end
@@ -0,0 +1,21 @@
1
+ CREATE TABLE posts (
2
+ id integer primary key,
3
+ user_id integer,
4
+ title text,
5
+ body text,
6
+ at date
7
+ );
8
+
9
+ CREATE TABLE users (
10
+ id integer primary key,
11
+ username text,
12
+ password text
13
+ );
14
+
15
+ CREATE TABLE comments (
16
+ id integer primary key,
17
+ post_id integer,
18
+ username text,
19
+ body text,
20
+ created_at date
21
+ );
Binary file
@@ -0,0 +1,16 @@
1
+ # Logfile created on Tue Jan 17 22:57:14 MST 2006 by logger.rb/1.5.2.4
2
+ Camping::Models::Post Load (0.000000) SQLite3::SQLException: no such table: posts: SELECT * FROM posts 
3
+ Camping::Models::Post Load (0.000764) SELECT * FROM posts 
4
+ Camping::Models::Post Load (0.000776) SELECT * FROM posts 
5
+ Camping::Models::Post Load (0.000781) SELECT * FROM posts 
6
+ Camping::Models::Post Load (0.000803) SELECT * FROM posts WHERE (posts.id = '1') LIMIT 1
7
+ Camping::Models::Post Load (0.000873) SELECT * FROM posts 
8
+ Camping::Models::Post Load (0.000825) SELECT * FROM posts 
9
+ Camping::Models::Post Load (0.000806) SELECT * FROM posts 
10
+ Camping::Models::Post Load (0.000824) SELECT * FROM posts 
11
+ Camping::Models::Post Load (0.000832) SELECT * FROM posts 
12
+ Camping::Models::Post Load (0.000816) SELECT * FROM posts 
13
+ Camping::Models::Post Load (0.000824) SELECT * FROM posts 
14
+ Camping::Models::Post Load (0.000813) SELECT * FROM posts 
15
+ Camping::Models::Post Load (0.000828) SELECT * FROM posts 
16
+ Camping::Models::User Load (0.000831) SELECT * FROM users WHERE (username = '_why' AND password = 'hacky') LIMIT 1
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/ruby
2
+ require 'webrick/httpserver'
3
+ s = WEBrick::HTTPServer.new(:BindAddress => 'localhost', :Port => 3044)
4
+ s.mount("/", WEBrick::HTTPServlet::CGIHandler, "blog.rb")
5
+ trap( :INT ) { s.shutdown }
6
+ s.start
@@ -0,0 +1,10 @@
1
+ body {
2
+ font-family: Utopia, Georga, serif;
3
+ }
4
+ h1.header {
5
+ background-color: #fef;
6
+ margin: 0; padding: 10px;
7
+ }
8
+ div.content {
9
+ padding: 10px;
10
+ }
@@ -0,0 +1,44 @@
1
+ %w[rubygems active_record markaby metaid ostruct].each {|lib| require lib}
2
+ module Camping;module Models;Base = ActiveRecord::Base;end;module Views;end
3
+ Markaby::Builder.class_eval{include Views};module Controllers;module RM
4
+ attr_accessor :input,:cookies,:headers,:body,:status;def method_missing(m,
5
+ *args, &blk);str=eval("markaby.#{m}(*args, &blk)");str=markaview(:layout){
6
+ str}rescue nil;r(200,str.to_s,'Content-Type'=>'text/html');end;def render(m)
7
+ str = markaview(m);str = markaview(:layout){ str }rescue nil;r(200, str,
8
+ "Content-Type" => 'text/html');end;def redirect(*args);c, *args = args;if \
9
+ c.respond_to? :urls;c = c.urls.first;c.gsub!(/\(.+?\)/) do;((a = args.
10
+ shift).respond_to?(:primary_key) ? a.method(a.primary_key) : a).to_s;end
11
+ end;r(302,'','Location' => c);end;def r(s, b, h = {});@status = s;@headers.
12
+ merge!(h);@body = b;end;def service(e, m, a);@status, @headers = 200,
13
+ {'Content-Type' => 'text/html'};@cookies=Camping.cookie_parse(e['COOKIE']||
14
+ e['HTTP_COOKIE']);cook = @cookies.marshal_dump.dup;if (e['REQUEST_METHOD']==
15
+ 'POST')and %r|\Amultipart/form-data.*boundary=\"?.+?\"?|n=~e['CONTENT_TYPE']
16
+ return r(500, "Urgh, multipart/form-data not yet supported.");else;@input =
17
+ Camping.qs_parse(e['REQUEST_METHOD']!="POST" ? e['QUERY_STRING'] : $stdin.
18
+ read(e['CONTENT_LENGTH'].to_i));end;@body = method( m.downcase ).call(*a)
19
+ @headers['Set-Cookie'] = @cookies.marshal_dump.map { |k,v| "#{k}=#{Camping.
20
+ escape(v)}; path=/"if v != cook[k]}.compact;self;end;def to_s;"Status: #{
21
+ @status}\n#{@headers.map{|k,v|v.to_a.map{|v2|"#{k}: #{v2}"}}.flatten.join(
22
+ "\n")}\n\n#{@body}";end;private;def markaby;Markaby::Builder.new(
23
+ instance_variables.map{|iv|[iv[1..-1].intern, instance_variable_get(iv)] },
24
+ {});end;def markaview(m,*args,&blk);markaby.instance_eval{Views.
25
+ instance_method(m).bind(self).call(*args, &blk); self }.to_s;end;end;class R
26
+ include RM end;class NotFound < R;def get;r(404,h1('Camping Problem!')+h2(
27
+ 'Not Found'))end end;class<<self;def R(*urls);Class.new(R){meta_def(
28
+ :inherited){|c|c.meta_def(:urls){urls}}}end;def D(path);constants.each{|c|
29
+ k=const_get(c);return k,$~[1..-1]if (k.urls rescue "/#{c.downcase}").find{
30
+ |x|path=~/^#{x}\/?$/ };};[NotFound, []]end end end;class Response; include
31
+ Controllers::RM;def initialize(s=200,&blk);@headers,@body,@status={},"",s
32
+ instance_eval &blk end end;class << self;def escape(s); s.to_s.gsub(/([^ \
33
+ a-zA-Z0-9_.-]+)/n){'%'+$1.unpack('H2'*$1.size).join('%').upcase}.tr(' ','+')
34
+ end;def unescape(s);s.tr('+',' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){[$1.delete(
35
+ '%')].pack('H*')}end;def qs_parse(qs,d='&;');OpenStruct.new((qs||'').split(
36
+ /[#{d}] */n).inject({}){|hsh, p|k,v=p.split('=',2).map{|v|unescape(v)};hsh[
37
+ k]=v unless v.empty?;hsh}) end;def cookie_parse(s);c=qs_parse(s,';,') end
38
+ def run;begin;k,a,m=Controllers.D(ENV['PATH_INFO'])+[ENV['REQUEST_METHOD']||
39
+ "GET"];k.class_eval{include Controllers::RM};o=k.new;o.class.class_eval do
40
+ Models.constants.each{|c|g=Models.const_get(c);remove_const c if
41
+ const_defined? c;const_set c,g};end;puts o.service(ENV, m, a);rescue=>e
42
+ puts Response.new(200){@headers['Content-Type']='text/html';@body=Markaby::
43
+ Builder.new({},{}){h1'Camping Problem!';h2"#{k}.#{m}";h3"#{e.class} \
44
+ #{e.message}:";ul{e.backtrace.each{|bt|li bt}}}.to_s};end end end end
data/lib/camping.rb ADDED
@@ -0,0 +1,105 @@
1
+ %w[rubygems active_record markaby metaid ostruct].each { |lib| require lib }
2
+
3
+ module Camping
4
+ module Models; end ; module Views; end ; Models::Base = ActiveRecord::Base
5
+ Markaby::Builder.class_eval { include Views }
6
+
7
+ module Controllers
8
+ module RM
9
+ attr_accessor :input, :cookies, :headers, :body, :status
10
+ def method_missing(m, *args, &blk)
11
+ str = eval("markaby.#{m}(*args, &blk)")
12
+ str = markaview(:layout) { str } rescue nil
13
+ r(200, str.to_s, 'Content-Type' => 'text/html')
14
+ end
15
+ def render(m)
16
+ str = markaview(m)
17
+ str = markaview(:layout) { str } rescue nil
18
+ r(200, str, "Content-Type" => 'text/html')
19
+ end
20
+ def redirect(*args)
21
+ c, *args = args
22
+ if c.respond_to? :urls
23
+ c = c.urls.first
24
+ c.gsub!(/\(.+?\)/) do
25
+ ((a = args.shift).respond_to?(:primary_key) ? a.method(a.primary_key) : a).to_s
26
+ end
27
+ end
28
+ r(302, '', 'Location' => c)
29
+ end
30
+ def r(s, b, h = {}); @status = s; @headers.merge!(h); @body = b; end
31
+ def service(e, m, a)
32
+ @status, @headers = 200, {'Content-Type' => 'text/html'}
33
+ @cookies = Camping.cookie_parse(e['HTTP_COOKIE'] || e['COOKIE'])
34
+ cook = @cookies.marshal_dump.dup
35
+ if ("POST" == e['REQUEST_METHOD']) and
36
+ %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(e['CONTENT_TYPE'])
37
+ return r(500, "Urgh, multipart/form-data not yet supported.")
38
+ else
39
+ @input = Camping.qs_parse(e['REQUEST_METHOD'] == "POST" ?
40
+ $stdin.read(e['CONTENT_LENGTH'].to_i) : e['QUERY_STRING'])
41
+ end
42
+
43
+ @body = method( m.downcase ).call(*a)
44
+ @headers['Set-Cookie'] = @cookies.marshal_dump.map { |k,v| "#{k}=#{Camping.escape(v)}; path=/" if v != cook[k] }.compact
45
+ self
46
+ end
47
+ def to_s
48
+ "Status: #{@status}\n#{@headers.map{|k,v|v.to_a.map{|v2|"#{k}: #{v2}"}}.flatten.join("\n")}\n\n#{@body}"
49
+ end
50
+ private
51
+ def markaby
52
+ Markaby::Builder.new( instance_variables.map { |iv|
53
+ [iv[1..-1].intern, instance_variable_get(iv)] }, {} )
54
+ end
55
+ def markaview(m, *args, &blk)
56
+ markaby.instance_eval { Views.instance_method(m).bind(self).call(*args, &blk); self }.to_s
57
+ end
58
+ end
59
+ class R; include RM end
60
+ class NotFound < R; def get; r(404, h1('Camping Problem!') + h2('Not Found')); end end
61
+
62
+ class << self
63
+ def R(*urls); Class.new(R) { meta_def(:inherited) { |c| c.meta_def(:urls) { urls } } }; end
64
+ def D(path)
65
+ constants.each do |c|
66
+ k = const_get(c)
67
+ return k, $~[1..-1] if (k.urls rescue "/#{c.downcase}").find { |x| path =~ /^#{x}\/?$/ }
68
+ end
69
+ [NotFound, []]
70
+ end
71
+ end
72
+ end
73
+
74
+ class Response; include Controllers::RM
75
+ def initialize(s = 200, &blk)
76
+ @headers, @body, @status = {}, "", s
77
+ instance_eval &blk
78
+ end
79
+ end
80
+
81
+ class << self
82
+ def escape(s); s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n){'%'+$1.unpack('H2'*$1.size).join('%').upcase}.tr(' ', '+') end
83
+ def unescape(s); s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){[$1.delete('%')].pack('H*')} end
84
+ def qs_parse(qs, d = '&;'); OpenStruct.new((qs||'').split(/[#{d}] */n).
85
+ inject({}){|hsh, p|k, v = p.split('=',2).map {|v| unescape(v)}; hsh[k] = v unless v.empty?; hsh}) end
86
+ def cookie_parse(s); c = qs_parse(s, ';,'); end
87
+ def run
88
+ begin
89
+ k, a, m = Controllers.D(ENV['PATH_INFO']) + [ENV['REQUEST_METHOD'] || "GET"]
90
+ k.class_eval { include Controllers::RM }
91
+ o = k.new
92
+ o.class.class_eval do
93
+ Models.constants.each do |c|
94
+ g = Models.const_get(c)
95
+ remove_const c if const_defined? c
96
+ const_set c, g
97
+ end
98
+ end
99
+ puts o.service(ENV, m, a)
100
+ rescue => e
101
+ puts Response.new(200) { @headers['Content-Type'] = 'text/html'; @body = Markaby::Builder.new({}, {}) { h1 'Camping Problem!'; h2 "#{k}.#{m}"; h3 "#{e.class} #{e.message}:"; ul { e.backtrace.each { |bt| li bt } } }.to_s }
102
+ end
103
+ end
104
+ end
105
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: camping
5
+ version: !ruby/object:Gem::Version
6
+ version: "1.0"
7
+ date: 2006-01-18 00:00:00 -07:00
8
+ summary: miniature rails for stay-at-home moms
9
+ require_paths:
10
+ - lib
11
+ email: why@ruby-lang.org
12
+ homepage: http://whytheluckystiff.net/camping/
13
+ rubyforge_project: hobix
14
+ description:
15
+ autorequire: camping
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - why the lucky stiff
31
+ files:
32
+ - examples/blog
33
+ - examples/blog/blog.sqlite3
34
+ - examples/blog/blog.rb
35
+ - examples/blog/camping.log
36
+ - examples/blog/start
37
+ - examples/blog/blog3.db
38
+ - examples/blog/styles.css
39
+ - lib/camping-mural.rb
40
+ - lib/camping.rb
41
+ test_files: []
42
+ rdoc_options: []
43
+ extra_rdoc_files: []
44
+ executables: []
45
+ extensions: []
46
+ requirements: []
47
+ dependencies:
48
+ - !ruby/object:Gem::Dependency
49
+ name: activerecord
50
+ version_requirement:
51
+ version_requirements: !ruby/object:Gem::Version::Requirement
52
+ requirements:
53
+ -
54
+ - ">"
55
+ - !ruby/object:Gem::Version
56
+ version: 0.0.0
57
+ version:
58
+ - !ruby/object:Gem::Dependency
59
+ name: markaby
60
+ version_requirement:
61
+ version_requirements: !ruby/object:Gem::Version::Requirement
62
+ requirements:
63
+ -
64
+ - ">"
65
+ - !ruby/object:Gem::Version
66
+ version: 0.0.0
67
+ version:
68
+ - !ruby/object:Gem::Dependency
69
+ name: metaid
70
+ version_requirement:
71
+ version_requirements: !ruby/object:Gem::Version::Requirement
72
+ requirements:
73
+ -
74
+ - ">"
75
+ - !ruby/object:Gem::Version
76
+ version: 0.0.0
77
+ version: