liars 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ Liars is a tiny MVC web framework.
2
+ ==================================
3
+
4
+ "liars" = "#{'rail'.reverse}s".
5
+ It's a very quick and dirty hack, just demonstrating some concepts. As its name said, Don't trust it. :-)
6
+
7
+ Install
8
+ =======
9
+
10
+ gem install liars.
11
+
12
+
13
+ Usage
14
+ =====
15
+
16
+ 1. Create a new scaffold file. The command below generates a scaffold ruby file named test.rb.
17
+ liars -s test
18
+ 2. Run it. The command below also generates a database file named db.yaml.
19
+ liars test.rb
20
+ 3. Now lauch your browser to <http://localhost:2008>
21
+
22
+ Help
23
+ ====
24
+
25
+ liars --help
26
+
27
+ An extra blog example:
28
+ ======================
29
+
30
+ Copy code below blog.rb to a new ruby file such as blog.rb, then run:
31
+
32
+ liars blog.rb -d blog.yaml
33
+
34
+ blog.rb:
35
+
36
+ module Liars
37
+ # Model ======================================================================
38
+ class Article < M
39
+ has_field :title
40
+ has_field :content
41
+ has_many :comments
42
+ end
43
+
44
+ class Comment < M
45
+ has_field :title
46
+ has_field :content
47
+ belongs_to :article
48
+ end
49
+
50
+ class ArticleC < C
51
+ route_of :index, '/', '/index', '/default'
52
+ def index
53
+ @articles = Article.find(:all)
54
+ render
55
+ end
56
+
57
+ route_of :show, '/show/(\d+)'
58
+ def show(id)
59
+ @article = Article.find(id.to_i)
60
+ render
61
+ end
62
+
63
+ route_of :create, '/create'
64
+ def create
65
+ Article.create(params[:article])
66
+ redirect_to '/'
67
+ end
68
+
69
+ route_of :add_comment, '/add_comment/(\d+)'
70
+ def add_comment(id)
71
+ @article = Article.find(id.to_i)
72
+ @article.comments << Comment.create(params[:comment])
73
+ @article.save
74
+ redirect_to "/show/#{id}"
75
+ end
76
+
77
+ route_of :style, '/styles.css'
78
+ def style
79
+ @headers["Content-Type"] = "text/css; charset=utf-8"
80
+ @body = %[
81
+ body {
82
+ font-family: Utopia, Georga, serif;
83
+ }
84
+ h1 {
85
+ background-color: #fef;
86
+ margin: 0; padding: 10px;
87
+ }
88
+ div {
89
+ padding: 10px;
90
+ }
91
+ ]
92
+ end
93
+ end
94
+
95
+ class ArticleV < V
96
+ def layout
97
+ html do
98
+ head do
99
+ title 'Liars never tell lies!'
100
+ link :rel => 'stylesheet', :type => 'text/css',
101
+ :href => '/styles.css', :media => 'screen'
102
+ end
103
+ body do
104
+ h1 { a 'Articles', :href => "/" }
105
+ div do
106
+ yield
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ def index
113
+ h1 'Articles'
114
+ hr
115
+ @articles.each do |ar|
116
+ b ar.title
117
+ p ar.content
118
+ a 'show comments', :href=> "/show/#{ar.id}"
119
+ hr
120
+ end
121
+ form :action=>'/create', :method=>'Post' do
122
+ input :type=>'text', :name=>'article[title]'; br
123
+ textarea '', :name=>'article[content]'; br
124
+ input :type=>'submit'
125
+ end
126
+ end
127
+
128
+ def show
129
+ h1 'Articles'
130
+ a 'index', :href=> "/"
131
+ hr
132
+ b @article.title
133
+ p @article.content
134
+ h1 'Comments'
135
+ hr
136
+ @article.comments.each do |c|
137
+ b c.title
138
+ p c.content
139
+ end
140
+ hr
141
+ form :action=> "/add_comment/#{@article.id}", :method=>'Post' do
142
+ input :type=>'text', :name=>'comment[title]'; br
143
+ textarea '', :name=>'comment[content]'; br
144
+ input :type=>'submit'
145
+ end
146
+ end
147
+ end
148
+ end
data/bin/liars CHANGED
@@ -16,16 +16,18 @@ if conf.rc and File.exists?( conf.rc )
16
16
  end
17
17
 
18
18
  opts = OptionParser.new do |opts|
19
- opts.banner = "用法: liars example.rb..."
20
- opts.define_head "Liars, 超小型的Ruby MVC Web开发框架 Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
19
+ opts.banner = "Liars, a tiny MVC web framework. "
20
+ # opts.define_head "Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
21
+ opts.separator "usage: liars -s test.rb && liars test.rb"
22
+ opts.separator "see http://github.com/luonet/liars for more details"
21
23
  opts.separator ""
22
- opts.separator " 选项列表:"
24
+ opts.separator "options:"
23
25
 
24
- opts.on("-h", "--host HOSTNAME", "Web服务器绑定地址(默认为#{conf.host})") { |conf.host| }
25
- opts.on("-p", "--port NUM", "Web服务器绑定端口(默认为#{conf.port})") { |conf.port| }
26
- opts.on("-d", "--database FILE", "数据库文件(默认为#{conf.db})") { |conf.db| }
27
- opts.on("-c", "--console", "运行在irb模式") { conf.server = :console }
28
- opts.on("-s", "--scaffold FILE", "快速创建一个模板") do |conf.scaffold|
26
+ opts.on("-h", "--host HOSTNAME", "web server host name(default #{conf.host})") { |conf.host| }
27
+ opts.on("-p", "--port NUM", "Web server binding port(default #{conf.port})") { |conf.port| }
28
+ opts.on("-d", "--database FILE", "database file (default #{conf.db})") { |conf.db| }
29
+ opts.on("-c", "--console", "running in irb mode") { conf.server = :console }
30
+ opts.on("-s", "--scaffold FILE", "generates a scaffold file") do |conf.scaffold|
29
31
  conf.scaffold =~ /^(\w+)(\.rb)?$/
30
32
  File.open("#{Dir.pwd}/#{$1}.rb", 'w') do |f|
31
33
  class_name = $1.singularize.camelize
@@ -61,19 +63,19 @@ module Liars
61
63
  end
62
64
  EOF
63
65
  end
64
- puts "模板文件#{$1}.rb创建成功"
66
+ puts "template #{$1}.rb generated"
65
67
  exit
66
68
  end
67
69
 
68
70
  opts.separator ""
69
- opts.separator "其他选项:"
71
+ opts.separator "other options:"
70
72
 
71
- opts.on_tail("-?", "--help", "显示帮助信息") do
73
+ opts.on_tail("-?", "--help", "show help messages") do
72
74
  puts opts
73
75
  exit
74
76
  end
75
77
 
76
- opts.on_tail("-v", "--version", "显示版本信息") do
78
+ opts.on_tail("-v", "--version", "show version") do
77
79
  class << Gem; attr_accessor :loaded_specs; end
78
80
  puts Gem.loaded_specs['liars'].version
79
81
  exit
@@ -95,7 +97,6 @@ if conf.server == :console
95
97
  ENV['IRBRC'] = ".irbrc" if File.exists? ".irbrc"
96
98
  IRB.start
97
99
  else
98
- # 建立数据库
99
100
  Liars::DbEngine.db_name = conf.db
100
101
  Liars::DbEngine.create_db
101
102
 
@@ -109,4 +110,4 @@ else
109
110
  Liars::DbEngine.write_db
110
111
  end
111
112
  s.start
112
- end
113
+ end
@@ -7,37 +7,37 @@ module Liars
7
7
  def subclasses; @@subclasses; end
8
8
 
9
9
  def run(r=$stdin, e=ENV)
10
- route = e['PATH_INFO']
11
- @@subclasses.each do |klass|
12
- action, args = klass.get_action_and_args(route)
13
- if action
14
- controller = klass.new(r, e, e['REQUEST_METHOD']||"GET")
15
- return controller.send(action, *args) && controller
16
- end
17
- end
10
+ route = e['PATH_INFO']
11
+ @@subclasses.each do |klass|
12
+ action, args = klass.get_action_and_args(route)
13
+ if action
14
+ controller = klass.new(r, e, e['REQUEST_METHOD']||"GET")
15
+ return controller.send(action, *args) && controller
16
+ end
17
+ end
18
18
  end
19
19
 
20
20
  def route_of(action, *routes)
21
- @@routes ||= {}
22
- @@routes[action] = routes
21
+ @@routes ||= {}
22
+ @@routes[action] = routes
23
23
  end
24
24
 
25
25
  # 实际上是返回一个action的名称和这个action所有可能用到的参数列表
26
26
  # 如edit上映射的route是'/edit/(\d+)',而实际访问的路径是'/edit/1'时
27
27
  # 1将会被作为一个参数传给edit方法
28
28
  def get_action_and_args(route)
29
- @@routes.each do |action, action_routes|
30
- action_routes.find do |r|
31
- match = Regexp.new("^#{r}$").match(route)
32
- return action, match[1..-1] if match
33
- end
29
+ @@routes.each do |action, action_routes|
30
+ action_routes.find do |r|
31
+ match = Regexp.new("^#{r}$").match(route)
32
+ return action, match[1..-1] if match
33
+ end
34
34
  end
35
35
  end
36
36
  end
37
37
 
38
38
  def initialize(r, e, m)
39
39
  @status, @method, @env, @headers, @root = 200, m.downcase, e,
40
- {'Content-Type'=>'text/html'}, e["SCRIPT_NAME"].sub(/\/$/,'')
40
+ {'Content-Type'=>'text/html'}, e["SCRIPT_NAME"].sub(/\/$/,'')
41
41
  @params = qsp(e["QUERY_STRING"])
42
42
  @cookies = kp(e["HTTP_COOKIE"])
43
43
  @params.merge!(qsp(r.read)) if @method == "post"
@@ -73,30 +73,30 @@ module Liars
73
73
 
74
74
  def qsp(qs, d='&;')
75
75
  (qs || '').split(/[#{d}] */n).inject({}) do |h, p|
76
- k, v = un(p).split('=', 2)
77
- if (k = k.split(/[\]\[]+/)).length == 1
78
- h[k[0].to_sym] = v
79
- else
80
- (h[k[0].to_sym] ||= {})[k[1].to_sym] = v
81
- end
82
- h
76
+ k, v = un(p).split('=', 2)
77
+ if (k = k.split(/[\]\[]+/)).length == 1
78
+ h[k[0].to_sym] = v
79
+ else
80
+ (h[k[0].to_sym] ||= {})[k[1].to_sym] = v
81
+ end
82
+ h
83
83
  end
84
84
  end
85
85
 
86
86
  def kp(s); qsp(s, ';,'); end
87
-
87
+
88
88
  def render(action=(caller[0]=~/`(\w+)'/;$1))
89
89
  # 查找当前controller对应的view,然后根据action来找到渲染方法
90
90
  name = (self.class.to_s =~ /(\w+)(C|Controller)$/; $1)
91
91
  view_class = eval("#{name}View") rescue eval("#{name}V")
92
92
  view_instance = view_class.new
93
93
  instance_variables.each do |iv|
94
- view_instance.instance_variable_set(iv, instance_variable_get(iv))
94
+ view_instance.instance_variable_set(iv, instance_variable_get(iv))
95
95
  end
96
96
  render_result = view_instance.respond_to?(:layout) ?
97
- view_instance.send(:layout, &view_instance.method(action)) :
98
- view_instance.send(action)
97
+ view_instance.send(:layout, &view_instance.method(action)) :
98
+ view_instance.send(action)
99
99
  @body = view_instance.stream || render_result
100
100
  end
101
101
  end
102
- end
102
+ end
data/lib/db.rb CHANGED
@@ -22,99 +22,99 @@ module Liars
22
22
  class DbEngine
23
23
  class << self
24
24
  def all_models
25
- @all_models ||= []
25
+ @all_models ||= []
26
26
  end
27
27
 
28
28
  def db_name
29
- @db_name || "db.yaml"
29
+ @db_name || "db.yaml"
30
30
  end
31
31
 
32
32
  def db_name=(name)
33
- @db_name = name
33
+ @db_name = name
34
34
  end
35
-
35
+
36
36
  def create_db
37
- return if File.exists?(db_name)
38
- data = all_models.inject({}) do |data_hash, model|
39
- data_hash[model.to_s.to_sym] = { :max_id=>0, :records=>[] }
40
- data_hash
41
- end
42
- write_db(data)
43
- end
44
-
37
+ return if File.exists?(db_name)
38
+ data = all_models.inject({}) do |data_hash, model|
39
+ data_hash[model.to_s.to_sym] = { :max_id=>0, :records=>[] }
40
+ data_hash
41
+ end
42
+ write_db(data)
43
+ end
44
+
45
45
  def write_db(data=nil)
46
- File.open(db_name, "w") {|f| YAML.dump((data || @db_data), f)}
46
+ File.open(db_name, "w") {|f| YAML.dump((data || @db_data), f)}
47
47
  end
48
48
 
49
49
  def db_data
50
- @db_data ||= YAML.load_file(db_name)
50
+ @db_data ||= YAML.load_file(db_name)
51
51
  end
52
52
 
53
53
  def records_of(klass)
54
- db_data[klass.to_s.to_sym][:records]
54
+ db_data[klass.to_s.to_sym][:records]
55
55
  end
56
56
 
57
57
  def record_of(obj)
58
- records_of(obj.class).find {|x| x[:id] == obj.id} if obj.id
58
+ records_of(obj.class).find {|x| x[:id] == obj.id} if obj.id
59
59
  end
60
60
 
61
61
  def increase_max_id_of(klass)
62
- db_data[klass.to_s.to_sym][:max_id] += 1
62
+ db_data[klass.to_s.to_sym][:max_id] += 1
63
63
  end
64
64
 
65
65
  def find(klass, ids)
66
- case ids
67
- when [] then []
68
- when :all then records_of(klass).collect {|r| klass.new(r)}
69
- when Array then find_records(klass, ids).collect! {|r| klass.new(r)}
70
- else find_records(klass, [ids]).collect! {|r| klass.new(r)}.first
66
+ case ids
67
+ when [] then []
68
+ when :all then records_of(klass).collect {|r| klass.new(r)}
69
+ when Array then find_records(klass, ids).collect! {|r| klass.new(r)}
70
+ else find_records(klass, [ids]).collect! {|r| klass.new(r)}.first
71
71
  end
72
72
  end
73
73
 
74
74
  def find_records(klass, ids)
75
- records_of(klass).select {|x| ids.include? x[:id]}
75
+ records_of(klass).select {|x| ids.include? x[:id]}
76
76
  end
77
77
 
78
78
  def insert(obj)
79
- records_of(obj.class) << obj.data
80
- obj
79
+ records_of(obj.class) << obj.data
80
+ obj
81
81
  end
82
82
 
83
83
  def delete(obj)
84
- records_of(obj.class).delete_if {|x| x[:id] == obj.id }
84
+ records_of(obj.class).delete_if {|x| x[:id] == obj.id }
85
85
  end
86
86
 
87
87
  def update(obj)
88
- record_of(obj).merge!(obj.data)
89
- obj
88
+ record_of(obj).merge!(obj.data)
89
+ obj
90
90
  end
91
91
 
92
92
  def save(obj)
93
- if obj.new?
94
- obj.instance_variable_set("@id", increase_max_id_of(obj.class))
95
- new_record = true
96
- end
97
- save_associations(obj)
98
- new_record ? insert(obj) : update(obj)
93
+ if obj.new?
94
+ obj.instance_variable_set("@id", increase_max_id_of(obj.class))
95
+ new_record = true
96
+ end
97
+ save_associations(obj)
98
+ new_record ? insert(obj) : update(obj)
99
99
  end
100
100
 
101
101
  def save_associations(obj)
102
- obj.class.associations.each do |assoc|
103
- assoc_type, assoc_name = assoc
104
- save_has_many_associations(obj, assoc_name) if assoc_type == :has_many
102
+ obj.class.associations.each do |assoc|
103
+ assoc_type, assoc_name = assoc
104
+ save_has_many_associations(obj, assoc_name) if assoc_type == :has_many
105
105
  end
106
106
  end
107
107
 
108
108
  def save_has_many_associations(obj, assoc_name)
109
- assoc_objs = obj.instance_variable_get("@#{assoc_name}_obj") || []
110
- assoc_ids = []
111
- assoc_objs.each do |assoc_obj|
112
- assoc_obj.instance_variable_set("@#{obj.class.to_s.underscore.sub(/.*\//, '')}", obj.id)
113
- assoc_obj.save
114
- assoc_ids << assoc_obj.id
115
- end
116
- obj.instance_variable_set("@#{assoc_name}", assoc_ids)
109
+ assoc_objs = obj.instance_variable_get("@#{assoc_name}_obj") || []
110
+ assoc_ids = []
111
+ assoc_objs.each do |assoc_obj|
112
+ assoc_obj.instance_variable_set("@#{obj.class.to_s.underscore.sub(/.*\//, '')}", obj.id)
113
+ assoc_obj.save
114
+ assoc_ids << assoc_obj.id
115
+ end
116
+ obj.instance_variable_set("@#{assoc_name}", assoc_ids)
117
117
  end
118
118
  end
119
119
  end
120
- end
120
+ end
@@ -24,7 +24,7 @@ module Liars
24
24
  @article = Article.find(id.to_i)
25
25
  render
26
26
  end
27
-
27
+
28
28
  route_of :create, '/create'
29
29
  def create
30
30
  Article.create(params[:article])
@@ -38,21 +38,21 @@ module Liars
38
38
  @article.save
39
39
  redirect_to "/show/#{id}"
40
40
  end
41
-
41
+
42
42
  route_of :style, '/styles.css'
43
43
  def style
44
44
  @headers["Content-Type"] = "text/css; charset=utf-8"
45
45
  @body = %[
46
- body {
47
- font-family: Utopia, Georga, serif;
48
- }
49
- h1 {
50
- background-color: #fef;
51
- margin: 0; padding: 10px;
52
- }
53
- div {
54
- padding: 10px;
55
- }
46
+ body {
47
+ font-family: Utopia, Georga, serif;
48
+ }
49
+ h1 {
50
+ background-color: #fef;
51
+ margin: 0; padding: 10px;
52
+ }
53
+ div {
54
+ padding: 10px;
55
+ }
56
56
  ]
57
57
  end
58
58
  end
@@ -60,33 +60,33 @@ module Liars
60
60
  class ArticleV < V
61
61
  def layout
62
62
  html do
63
- head do
64
- title 'Liars never tell lies!'
65
- link :rel => 'stylesheet', :type => 'text/css',
66
- :href => '/styles.css', :media => 'screen'
67
- end
68
- body do
69
- h1 { a 'Articles', :href => "http://www.google.cn" }
70
- div do
71
- yield
72
- end
73
- end
63
+ head do
64
+ title 'Liars never tell lies!'
65
+ link :rel => 'stylesheet', :type => 'text/css',
66
+ :href => '/styles.css', :media => 'screen'
67
+ end
68
+ body do
69
+ h1 { a 'Articles', :href => "/" }
70
+ div do
71
+ yield
72
+ end
73
+ end
74
74
  end
75
75
  end
76
-
76
+
77
77
  def index
78
78
  h1 'Articles'
79
79
  hr
80
80
  @articles.each do |ar|
81
- b ar.title
82
- p ar.content
83
- a 'show comments', :href=> "/show/#{ar.id}"
84
- hr
81
+ b ar.title
82
+ p ar.content
83
+ a 'show comments', :href=> "/show/#{ar.id}"
84
+ hr
85
85
  end
86
86
  form :action=>'/create', :method=>'Post' do
87
- input :type=>'text', :name=>'article[title]'; br
88
- textarea '', :name=>'article[content]'; br
89
- input :type=>'submit'
87
+ input :type=>'text', :name=>'article[title]'; br
88
+ textarea '', :name=>'article[content]'; br
89
+ input :type=>'submit'
90
90
  end
91
91
  end
92
92
 
@@ -99,14 +99,14 @@ module Liars
99
99
  h1 'Comments'
100
100
  hr
101
101
  @article.comments.each do |c|
102
- b c.title
103
- p c.content
102
+ b c.title
103
+ p c.content
104
104
  end
105
105
  hr
106
106
  form :action=> "/add_comment/#{@article.id}", :method=>'Post' do
107
- input :type=>'text', :name=>'comment[title]'; br
108
- textarea '', :name=>'comment[content]'; br
109
- input :type=>'submit'
107
+ input :type=>'text', :name=>'comment[title]'; br
108
+ textarea '', :name=>'comment[content]'; br
109
+ input :type=>'submit'
110
110
  end
111
111
  end
112
112
  end
@@ -187,4 +187,4 @@ module Liars
187
187
  # end
188
188
  # end
189
189
  # end
190
- end
190
+ end
@@ -21,69 +21,69 @@ module Liars
21
21
 
22
22
  class << self
23
23
  def inherited(child)
24
- DbEngine.all_models << child
24
+ DbEngine.all_models << child
25
25
  end
26
26
 
27
27
  def fields
28
- @fields ||= [:id]
28
+ @fields ||= [:id]
29
29
  end
30
30
 
31
31
  def associations
32
- (@associations ||= [])
32
+ (@associations ||= [])
33
33
  end
34
34
 
35
35
  def fields_and_associations
36
- fields + associations.collect {|x| x[1]}
36
+ fields + associations.collect {|x| x[1]}
37
37
  end
38
38
 
39
39
  def create(fields={})
40
- self.new(fields).save
40
+ self.new(fields).save
41
41
  end
42
42
 
43
43
  def find(ids)
44
- DbEngine.find(self, ids)
44
+ DbEngine.find(self, ids)
45
45
  end
46
46
 
47
47
  def has_field(name)
48
- attr_accessor name
49
- fields << name
48
+ attr_accessor name
49
+ fields << name
50
50
  end
51
51
 
52
52
  def has_many(name)
53
- class_name = name.singularize.camelize
54
- associations << [:has_many, name]
55
- class_eval <<-EOF
53
+ class_name = name.singularize.camelize
54
+ associations << [:has_many, name]
55
+ class_eval <<-EOF
56
56
  def #{name}
57
57
  @#{name} ||= []
58
58
  @#{name}_obj ||= DbEngine.find(#{class_name}, @#{name})
59
59
  end
60
-
60
+
61
61
  def #{name}=(value)
62
62
  @#{name}_obj = value
63
63
  end
64
- EOF
64
+ EOF
65
65
  end
66
66
 
67
67
  def belongs_to(name)
68
- class_name = name.camelize
69
- associations << [:belongs_to, name]
70
- class_eval <<-EOF
68
+ class_name = name.camelize
69
+ associations << [:belongs_to, name]
70
+ class_eval <<-EOF
71
71
  def #{name}
72
72
  @#{name}_obj ||= DbEngine.find(#{class_name}, @#{name})
73
73
  end
74
-
74
+
75
75
  def #{name}=(value)
76
76
  @#{name} = value.id
77
77
  @#{name}_obj = value
78
78
  end
79
- EOF
79
+ EOF
80
80
  end
81
81
  end
82
82
 
83
83
  def save
84
84
  DbEngine.save(self)
85
85
  end
86
-
86
+
87
87
  def new?
88
88
  @id == nil
89
89
  end
@@ -96,4 +96,4 @@ module Liars
96
96
  DbEngine.delete(self)
97
97
  end
98
98
  end
99
- end
99
+ end
@@ -7,17 +7,18 @@ module Liars
7
7
  super(server, klass)
8
8
  @klass = klass
9
9
  end
10
+
10
11
  # Handler for WEBrick requests (also aliased as do_POST).
11
12
  def service(req, resp)
12
13
  controller = @klass.run((req.body && StringIO.new(req.body)), req.meta_vars)
13
14
  resp.body = controller.body.to_s
14
15
  resp.status = controller.status
15
16
  controller.headers.each do |k, v|
16
- unless k =~ /^X-SENDFILE$/i
17
- [*v].each do |vi|
18
- resp[k] = vi
19
- end
20
- end
17
+ unless k =~ /^X-SENDFILE$/i
18
+ [*v].each do |vi|
19
+ resp[k] = vi
20
+ end
21
+ end
21
22
  end
22
23
  end
23
24
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - luonet
@@ -14,25 +14,20 @@ autorequire: liars
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-21 00:00:00 +08:00
17
+ date: 2010-04-06 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
21
- description: !binary |
22
- 5pyA5bCP5YyW55qETVZD5qGG5p62
23
-
21
+ description: It's a very quick and dirty hack, just demonstrating some concepts. As its name said, Do not trust it. :-)
24
22
  email: luoxin.net@gmail.com
25
23
  executables:
26
24
  - liars
27
25
  extensions: []
28
26
 
29
- extra_rdoc_files:
30
- - README
31
- - CHANGELOG
27
+ extra_rdoc_files: []
28
+
32
29
  files:
33
- - CHANGELOG
34
- - README
35
- - Rakefile
30
+ - README.markdown
36
31
  - liars.rb
37
32
  - bin/liars
38
33
  - lib/server.rb
@@ -42,24 +37,13 @@ files:
42
37
  - lib/example.rb
43
38
  - lib/db.rb
44
39
  - lib/model.rb
45
- - extras/flipbook_rdoc.rb
46
40
  has_rdoc: true
47
41
  homepage: http://luoxin.net/
48
42
  licenses: []
49
43
 
50
44
  post_install_message:
51
- rdoc_options:
52
- - --quiet
53
- - --title
54
- - Camping, the Documentation
55
- - --opname
56
- - index.html
57
- - --line-numbers
58
- - --main
59
- - README
60
- - --inline-source
61
- - --exclude
62
- - ^(examples|extras)\/
45
+ rdoc_options: []
46
+
63
47
  require_paths:
64
48
  - .
65
49
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -82,8 +66,6 @@ rubyforge_project:
82
66
  rubygems_version: 1.3.6
83
67
  signing_key:
84
68
  specification_version: 3
85
- summary: !binary |
86
- 5pyA5bCP5YyW55qETVZD5qGG5p62
87
-
69
+ summary: tiny MVC web framework
88
70
  test_files: []
89
71
 
data/CHANGELOG DELETED
File without changes
data/README DELETED
File without changes
data/Rakefile DELETED
@@ -1,69 +0,0 @@
1
- require 'rake'
2
- require 'rake/clean'
3
- require 'rake/gempackagetask'
4
- require 'rake/rdoctask'
5
- require 'fileutils'
6
- include FileUtils
7
-
8
- NAME = "liars"
9
- VERS = "0.0.2"
10
- CLEAN.include ['**/.*.sw?', '*.gem', '.config']
11
- RDOC_OPTS = ['--quiet', '--title', "Camping, the Documentation",
12
- "--opname", "index.html",
13
- "--line-numbers",
14
- "--main", "README",
15
- "--inline-source"]
16
-
17
- # platform = if ENV['HOME'] then "POSIX" elsif ENV['APPDATA'] then "MSWIN" end
18
-
19
- desc "将liars gem打包"
20
- task :default => [:package]
21
- task :package => [:clean]
22
-
23
- task :doc => [:before_doc, :rdoc, :after_doc]
24
-
25
- Rake::RDocTask.new do |rdoc|
26
- rdoc.rdoc_dir = 'doc/rdoc'
27
- rdoc.options += RDOC_OPTS
28
- rdoc.template = "extras/flipbook_rdoc.rb"
29
- rdoc.main = "README"
30
- rdoc.title = "Liars文档"
31
- rdoc.rdoc_files.add ['README', 'CHANGELOG','lib/*.rb']
32
- end
33
-
34
- spec =
35
- Gem::Specification.new do |s|
36
- s.name = NAME
37
- s.version = VERS
38
- s.platform = Gem::Platform::RUBY
39
- s.has_rdoc = true
40
- s.extra_rdoc_files = ["README", "CHANGELOG"]
41
- s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)\/']
42
- s.summary = "最小化的MVC框架"
43
- s.description = s.summary
44
- s.author = "luonet"
45
- s.email = 'luoxin.net@gmail.com'
46
- s.homepage = 'http://luoxin.net/'
47
- s.executables = ['liars']
48
-
49
- s.files = %w(CHANGELOG README Rakefile liars.rb) +
50
- Dir.glob("{bin,doc,test,lib,extras}/**/*")
51
-
52
- s.require_path = "."
53
- s.autorequire = 'liars'
54
- s.bindir = "bin"
55
- end
56
-
57
- Rake::GemPackageTask.new(spec) do |p|
58
- p.need_tar = ENV['APPDATA'].nil?
59
- p.gem_spec = spec
60
- end
61
-
62
- task :install do
63
- sh %{rake package}
64
- sh %{sudo gem install pkg/#{NAME}-#{VERS}}
65
- end
66
-
67
- task :uninstall => [:clean] do
68
- sh %{sudo gem uninstall #{NAME}}
69
- end
@@ -1,491 +0,0 @@
1
- CAMPING_EXTRAS_DIR = File.expand_path(File.dirname(__FILE__))
2
-
3
- module Generators
4
- class HTMLGenerator
5
- def generate_html
6
- @files_and_classes = {
7
- 'allfiles' => gen_into_index(@files),
8
- 'allclasses' => gen_into_index(@classes),
9
- "initial_page" => main_url,
10
- 'realtitle' => CGI.escapeHTML(@options.title),
11
- 'charset' => @options.charset
12
- }
13
-
14
- # the individual descriptions for files and classes
15
- gen_into(@files)
16
- gen_into(@classes)
17
- gen_main_index
18
-
19
- # this method is defined in the template file
20
- write_extra_pages if defined? write_extra_pages
21
- end
22
-
23
- def gen_into(list)
24
- hsh = @files_and_classes.dup
25
- list.each do |item|
26
- if item.document_self
27
- op_file = item.path
28
- hsh['root'] = item.path.split("/").map { ".." }[1..-1].join("/")
29
- item.instance_variable_set("@values", hsh)
30
- File.makedirs(File.dirname(op_file))
31
- File.open(op_file, "w") { |file| item.write_on(file) }
32
- end
33
- end
34
- end
35
-
36
- def gen_into_index(list)
37
- res = []
38
- list.each do |item|
39
- hsh = item.value_hash
40
- hsh['href'] = item.path
41
- hsh['name'] = item.index_name
42
- res << hsh
43
- end
44
- res
45
- end
46
-
47
- def gen_main_index
48
- template = TemplatePage.new(RDoc::Page::INDEX)
49
- File.open("index.html", "w") do |f|
50
- values = @files_and_classes.dup
51
- if @options.inline_source
52
- values['inline_source'] = true
53
- end
54
- template.write_html_on(f, values)
55
- end
56
- ['Camping.gif', 'permalink.gif'].each do |img|
57
- ipath = File.join(CAMPING_EXTRAS_DIR, img)
58
- File.copy(ipath, img)
59
- end
60
- end
61
- end
62
- end
63
-
64
-
65
- module RDoc
66
- module Page
67
- ######################################################################
68
- #
69
- # The following is used for the -1 option
70
- #
71
-
72
- FONTS = "verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif"
73
-
74
- STYLE = %{
75
- body, th, td {
76
- font: normal 14px verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif;
77
- line-height: 160%;
78
- padding: 0; margin: 0;
79
- margin-bottom: 30px;
80
- /* background-color: #402; */
81
- background-color: #694;
82
- }
83
- h1, h2, h3, h4 {
84
- font-family: Utopia, Georgia, serif;
85
- font-weight: bold;
86
- letter-spacing: -0.018em;
87
- }
88
- h1 { font-size: 24px; margin: .15em 1em 0 0 }
89
- h2 { font-size: 24px }
90
- h3 { font-size: 19px }
91
- h4 { font-size: 17px; font-weight: normal; }
92
- h4.ruled { border-bottom: solid 1px #CC9; }
93
- h2.ruled { padding-top: 35px; border-top: solid 1px #AA5; }
94
-
95
- /* Link styles */
96
- :link, :visited {
97
- color: #00b;
98
- }
99
- :link:hover, :visited:hover {
100
- background-color: #eee;
101
- color: #B22;
102
- }
103
- #fullpage {
104
- width: 720px;
105
- margin: 0 auto;
106
- }
107
- .page_shade, .page {
108
- padding: 0px 5px 5px 0px;
109
- background-color: #fcfcf9;
110
- border: solid 1px #983;
111
- }
112
- .page {
113
- margin-left: -5px;
114
- margin-top: -5px;
115
- padding: 20px 35px;
116
- }
117
- .page .header {
118
- float: right;
119
- color: #777;
120
- font-size: 10px;
121
- }
122
- .page h1, .page h2, .page h3 {
123
- clear: both;
124
- text-align: center;
125
- }
126
- #pager {
127
- padding: 10px 4px;
128
- color: white;
129
- font-size: 11px;
130
- }
131
- #pager :link, #pager :visited {
132
- color: #bfb;
133
- padding: 0px 5px;
134
- }
135
- #pager :link:hover, #pager :visited:hover {
136
- background-color: #262;
137
- color: white;
138
- }
139
- #logo { float: left; }
140
- #menu { background-color: #dfa; padding: 4px 12px; margin: 0; }
141
- #menu h3 { padding: 0; margin: 0; }
142
- #menu #links { float: right; }
143
- pre { font-weight: bold; color: #730; }
144
- tt { color: #703; font-size: 12pt; }
145
- .dyn-source { background-color: #775915; padding: 4px 8px; margin: 0; display: none; }
146
- .dyn-source pre { color: #DDDDDD; font-size: 8pt; }
147
- .source-link { text-align: right; font-size: 8pt; }
148
- .ruby-comment { color: green; font-style: italic }
149
- .ruby-constant { color: #CCDDFF; font-weight: bold; }
150
- .ruby-identifier { color: #CCCCCC; }
151
- .ruby-ivar { color: #BBCCFF; }
152
- .ruby-keyword { color: #EEEEFF; font-weight: bold }
153
- .ruby-node { color: #FFFFFF; }
154
- .ruby-operator { color: #CCCCCC; }
155
- .ruby-regexp { color: #DDFFDD; }
156
- .ruby-value { color: #FFAAAA; font-style: italic }
157
- .kw { color: #DDDDFF; font-weight: bold }
158
- .cmt { color: #CCFFCC; font-style: italic }
159
- .str { color: #EECCCC; font-style: italic }
160
- .re { color: #EECCCC; }
161
- }
162
-
163
- CONTENTS_XML = %{
164
- IF:description
165
- %description%
166
- ENDIF:description
167
-
168
- IF:requires
169
- <h4>Requires:</h4>
170
- <ul>
171
- START:requires
172
- IF:aref
173
- <li><a href="%aref%">%name%</a></li>
174
- ENDIF:aref
175
- IFNOT:aref
176
- <li>%name%</li>
177
- ENDIF:aref
178
- END:requires
179
- </ul>
180
- ENDIF:requires
181
-
182
- IF:attributes
183
- <h4>Attributes</h4>
184
- <table>
185
- START:attributes
186
- <tr><td>%name%</td><td>%rw%</td><td>%a_desc%</td></tr>
187
- END:attributes
188
- </table>
189
- ENDIF:attributes
190
-
191
- IF:includes
192
- <h4>Includes</h4>
193
- <ul>
194
- START:includes
195
- IF:aref
196
- <li><a href="%aref%">%name%</a></li>
197
- ENDIF:aref
198
- IFNOT:aref
199
- <li>%name%</li>
200
- ENDIF:aref
201
- END:includes
202
- </ul>
203
- ENDIF:includes
204
-
205
- START:sections
206
- IF:method_list
207
- <h2 class="ruled">Methods</h2>
208
- START:method_list
209
- IF:methods
210
- START:methods
211
- <h4 class="ruled">%type% %category% method:
212
- IF:callseq
213
- <strong><a name="%aref%">%callseq%</a></strong> <a href="#%aref%"><img src="%root%/permalink.gif" border="0" title="Permalink to %callseq%" /></a>
214
- ENDIF:callseq
215
- IFNOT:callseq
216
- <strong><a name="%aref%">%name%%params%</a></strong> <a href="#%aref%"><img src="%root%/permalink.gif" border="0" title="Permalink to %type% %category% method: %name%" /></a></h4>
217
- ENDIF:callseq
218
-
219
- IF:m_desc
220
- %m_desc%
221
- ENDIF:m_desc
222
-
223
- IF:sourcecode
224
- <div class="sourcecode">
225
- <p class="source-link">[ <a href="javascript:toggleSource('%aref%_source')" id="l_%aref%_source">show source</a> ]</p>
226
- <div id="%aref%_source" class="dyn-source">
227
- <pre>
228
- %sourcecode%
229
- </pre>
230
- </div>
231
- </div>
232
- ENDIF:sourcecode
233
- END:methods
234
- ENDIF:methods
235
- END:method_list
236
- ENDIF:method_list
237
- END:sections
238
- }
239
-
240
- ############################################################################
241
-
242
-
243
- BODY = %{
244
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
245
- <html>
246
- <head>
247
- <title>
248
- IF:title
249
- %realtitle% &raquo; %title%
250
- ENDIF:title
251
- IFNOT:title
252
- %realtitle%
253
- ENDIF:title
254
- </title>
255
- <meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
256
- <link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
257
- <script language="JavaScript" type="text/javascript">
258
- // <![CDATA[
259
-
260
- function toggleSource( id )
261
- {
262
- var elem
263
- var link
264
-
265
- if( document.getElementById )
266
- {
267
- elem = document.getElementById( id )
268
- link = document.getElementById( "l_" + id )
269
- }
270
- else if ( document.all )
271
- {
272
- elem = eval( "document.all." + id )
273
- link = eval( "document.all.l_" + id )
274
- }
275
- else
276
- return false;
277
-
278
- if( elem.style.display == "block" )
279
- {
280
- elem.style.display = "none"
281
- link.innerHTML = "show source"
282
- }
283
- else
284
- {
285
- elem.style.display = "block"
286
- link.innerHTML = "hide source"
287
- }
288
- }
289
-
290
- function openCode( url )
291
- {
292
- window.open( url, "SOURCE_CODE", "width=400,height=400,scrollbars=yes" )
293
- }
294
- // ]]>
295
- </script>
296
- </head>
297
- <body>
298
- <div id="menu">
299
- <div id="links">
300
- <a href="http://redhanded.hobix.com/bits/campingAMicroframework.html">backstory</a> |
301
- <a href="http://code.whytheluckystiff.net/camping/">wiki</a> |
302
- <a href="http://code.whytheluckystiff.net/camping/newticket">bugs</a> |
303
- <a href="http://code.whytheluckystiff.net/svn/camping/">svn</a>
304
- </div>
305
- <h3 class="title">%title%</h3>
306
- </div>
307
- <div id="fullpage">
308
- <div id="logo"><img src="%root%/Camping.gif" /></div>
309
- <div id="pager">
310
- <strong>Files:</strong>
311
- START:allfiles
312
- <a href="%root%/%href%" value="%title%">%name%</a>
313
- END:allfiles
314
- IF:allclasses
315
- |
316
- <strong>classes:</strong>
317
- START:allclasses
318
- <a href="%root%/%href%" title="%title%">%name%</a>
319
- END:allclasses
320
- ENDIF:allclasses
321
- </ul>
322
- </div>
323
-
324
- !INCLUDE!
325
-
326
- </div>
327
- </body>
328
- </html>
329
- }
330
-
331
- ###############################################################################
332
-
333
- FILE_PAGE = <<_FILE_PAGE_
334
- <div id="%full_path%" class="page_shade">
335
- <div class="page">
336
- <div class="header">
337
- <div class="path">%full_path% / %dtm_modified%</div>
338
- </div>
339
- #{CONTENTS_XML}
340
- </div>
341
- </div>
342
- _FILE_PAGE_
343
-
344
- ###################################################################
345
-
346
- CLASS_PAGE = %{
347
- <div id="%full_name%" class="page_shade">
348
- <div class="page">
349
- IF:parent
350
- <h3>%classmod% %full_name% &lt; HREF:par_url:parent:</h3>
351
- ENDIF:parent
352
- IFNOT:parent
353
- <h3>%classmod% %full_name%</h3>
354
- ENDIF:parent
355
-
356
- IF:infiles
357
- (in files
358
- START:infiles
359
- HREF:full_path_url:full_path:
360
- END:infiles
361
- )
362
- ENDIF:infiles
363
- } + CONTENTS_XML + %{
364
- </div>
365
- </div>
366
- }
367
-
368
- ###################################################################
369
-
370
- METHOD_LIST = %{
371
- IF:includes
372
- <div class="tablesubsubtitle">Included modules</div><br>
373
- <div class="name-list">
374
- START:includes
375
- <span class="method-name">HREF:aref:name:</span>
376
- END:includes
377
- </div>
378
- ENDIF:includes
379
-
380
- IF:method_list
381
- START:method_list
382
- IF:methods
383
- <table cellpadding=5 width="100%">
384
- <tr><td class="tablesubtitle">%type% %category% methods</td></tr>
385
- </table>
386
- START:methods
387
- <table width="100%" cellspacing = 0 cellpadding=5 border=0>
388
- <tr><td class="methodtitle">
389
- <a name="%aref%">
390
- IF:callseq
391
- <b>%callseq%</b>
392
- ENDIF:callseq
393
- IFNOT:callseq
394
- <b>%name%</b>%params%
395
- ENDIF:callseq
396
- IF:codeurl
397
- <a href="%codeurl%" target="source" class="srclink">src</a>
398
- ENDIF:codeurl
399
- </a></td></tr>
400
- </table>
401
- IF:m_desc
402
- <div class="description">
403
- %m_desc%
404
- </div>
405
- ENDIF:m_desc
406
- IF:aka
407
- <div class="aka">
408
- This method is also aliased as
409
- START:aka
410
- <a href="%aref%">%name%</a>
411
- END:aka
412
- </div>
413
- ENDIF:aka
414
- IF:sourcecode
415
- <div class="sourcecode">
416
- <p class="source-link">[ <a href="javascript:toggleSource('%aref%_source')" id="l_%aref%_source">show source</a> ]</p>
417
- <div id="%aref%_source" class="dyn-source">
418
- <pre>
419
- %sourcecode%
420
- </pre>
421
- </div>
422
- </div>
423
- ENDIF:sourcecode
424
- END:methods
425
- ENDIF:methods
426
- END:method_list
427
- ENDIF:method_list
428
- }
429
-
430
-
431
- ########################## Index ################################
432
-
433
- FR_INDEX_BODY = %{
434
- !INCLUDE!
435
- }
436
-
437
- FILE_INDEX = %{
438
- <html>
439
- <head>
440
- <meta http-equiv="Content-Type" content="text/html; charset=%charset%">
441
- <style>
442
- <!--
443
- body {
444
- background-color: #ddddff;
445
- font-family: #{FONTS};
446
- font-size: 11px;
447
- font-style: normal;
448
- line-height: 14px;
449
- color: #000040;
450
- }
451
- div.banner {
452
- background: #0000aa;
453
- color: white;
454
- padding: 1;
455
- margin: 0;
456
- font-size: 90%;
457
- font-weight: bold;
458
- line-height: 1.1;
459
- text-align: center;
460
- width: 100%;
461
- }
462
-
463
- -->
464
- </style>
465
- <base target="docwin">
466
- </head>
467
- <body>
468
- <div class="banner">%list_title%</div>
469
- START:entries
470
- <a href="%href%">%name%</a><br>
471
- END:entries
472
- </body></html>
473
- }
474
-
475
- CLASS_INDEX = FILE_INDEX
476
- METHOD_INDEX = FILE_INDEX
477
-
478
- INDEX = %{
479
- <HTML>
480
- <HEAD>
481
- <META HTTP-EQUIV="refresh" content="0;URL=%initial_page%">
482
- <TITLE>%realtitle%</TITLE>
483
- </HEAD>
484
- <BODY>
485
- Click <a href="%initial_page%">here</a> to open the Camping docs.
486
- </BODY>
487
- </HTML>
488
- }
489
-
490
- end
491
- end