soxer 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,34 @@
1
+ = 0.9.5 / 2010-10-00
2
+
3
+ * Inline documentation has been adjusted and slightly improved.
4
+
5
+ * The value of settings.origin is now a global system path, rather than a
6
+ local path from settings.root. Default is set to 'content', but you can
7
+ change it by Sinatra's standards.
8
+
9
+ * Atom file as progressed from -atom to .atom (dot atom) and soxer will now
10
+ server /any/path/to/file.atom with the application/atom+xml content type.
11
+
12
+ * Soxer has been modularized to Sinatra's standards, with the exception of
13
+ the name. It's still named soxer and not sinatra-soxer. This might change
14
+ in the future as we hit stable.
15
+
16
+ * Changed get_list method. It only accepts a block for filtering yaml files
17
+ Any sorting is now done by Array.sort {} afterwards.
18
+
19
+ * Fixed partial generator so it properly handles strings and symbols
20
+
21
+ * Cleaned up "soxer test" and only choose "thin" webserver if available.
22
+ Defaults to webrick (very slow).
23
+
24
+ = 0.9.4 / 2010-10-27
25
+
26
+ * Added executable 'soxer' to help generating application directories and
27
+ running developement versions
28
+
29
+ * Added skeletal directories, and 'empty' skeleton application
30
+
31
+ = 0.9.0 / 2010-10-24
32
+
33
+ * Initial release
34
+
data/bin/soxer CHANGED
@@ -85,7 +85,6 @@ def create
85
85
  FileUtils.mkdir(dir)
86
86
  FileUtils.cp_r(src+"/.", dir)
87
87
  return notice "Successfuly created '"+dir+"' Directory."
88
- #return Dir.glob(src+"/**/*").to_s
89
88
  else
90
89
  return err 'The destination directory exists.'
91
90
  end
@@ -96,27 +95,21 @@ end
96
95
 
97
96
  def test
98
97
  port = $*[1]!=nil ? $*[1] : '9394'
99
- server = false
100
- servers = %w[webrick mongrel thin]
101
- servers.each do |s|
102
- ENV['PATH'].split(':').each {|folder| server = s if File.exists?(folder+'/'+s)}
103
- end
104
- if server!=false
105
- system("rackup -s #{server} -p #{port}")
106
- return notice "End of developement mode."
107
- else
108
- return err "Please install a sinatra compatible web server (thin, mongrel or webrick.)"
109
- end
98
+ server = 'webrick'
99
+ ENV['PATH'].split(':').each {|folder| server = 'thin' if File.exists?(folder+'/thin')}
100
+ x = system("rackup -s #{server} -p #{port}")
101
+ return "Developement mode ends."
110
102
  end
111
103
 
112
104
  case $*[0]
113
105
  when 'create' then printf create
114
106
  when 'test' then printf test
107
+ when 'prank' then printf prank
115
108
  when 'help' then printf @help
116
109
  else printf err 'You did not specify an action!'
117
110
  end
118
111
 
119
-
112
+ # TO COME LATER
120
113
  x = <<END
121
114
  #{b 'corporate'} - Creates a corporate web page mockup
122
115
  #{b 'blog'} - Creates a blog mockup
data/lib/soxer/main.rb CHANGED
@@ -5,7 +5,7 @@ require 'uuid'
5
5
 
6
6
 
7
7
  module Sinatra
8
-
8
+
9
9
  #== Soxer, the web publishing tool.
10
10
  #
11
11
  # Soxer is a Sinatra module that adds additional methods to sinatra routes.
@@ -20,6 +20,14 @@ module Sinatra
20
20
  # License: Distributed under the GPL licence. http://www.gnu.org/licenses/gpl.html
21
21
  module Soxer
22
22
 
23
+ # === The Filereader class
24
+ #
25
+ # In addition to reading the YAML file it also adds two fields to the file:
26
+ # uuid: Universally Unique Identifier for atom and other feeds. Please, note
27
+ # that this id is not compared to other uuids. When creating a new
28
+ # document it's best to let soxer generate it.
29
+ # date: A standard date field. When creating a new document it's best to
30
+ # let soxer generate it.
23
31
  class Filereader
24
32
  attr_accessor :filename
25
33
 
@@ -32,7 +40,7 @@ module Sinatra
32
40
  out = YAML.load_file( @filename )
33
41
  add_date unless out['date']
34
42
  add_id unless out['uuid']
35
- out['url'] = @filename.gsub(/#{@s.root}\/#{@s.origin}(.+)\.yaml$/, "\\1" ).gsub(/(.+)\/index$/, "\\1" )
43
+ out['url'] = @filename.gsub(/#{@s.origin}(.+)\.yaml$/, "\\1" ).gsub(/(.+)\/index$/, "\\1" )
36
44
  out['mtime'] = File.mtime( @filename )
37
45
  out
38
46
  end
@@ -59,6 +67,12 @@ module Sinatra
59
67
  end
60
68
  end
61
69
 
70
+ # === The Urlreader class
71
+ #
72
+ # Urlreader simply checks if the URL recieved can be matched to a file.
73
+ # Currelntly it either matches a file path (ending with .yaml) from origin
74
+ # (the default is "content" directory within application root) or a
75
+ # directory path with index.yaml
62
76
  class Urlreader
63
77
  attr_accessor :url
64
78
 
@@ -69,8 +83,8 @@ module Sinatra
69
83
  def get_content
70
84
  self.settings
71
85
  fn = case true
72
- when File.exist?( f = File.join( @s.root, @s.origin, @url+'.yaml' ) ) then f
73
- when File.exist?( f = File.join( @s.root, @s.origin, @url+'/index.yaml' ) ) then f
86
+ when File.exist?( f = File.join( @s.origin, @url+'.yaml' ) ) then f
87
+ when File.exist?( f = File.join( @s.origin, @url+'/index.yaml' ) ) then f
74
88
  else throw :halt, [404, "Document not found"]
75
89
  end
76
90
  out = Filereader.new
@@ -78,158 +92,190 @@ module Sinatra
78
92
  out.get_content
79
93
  end
80
94
  end
81
-
82
- # === The "get_page", the document reading function
83
- #
84
- # Read the document in yaml format (with .yaml) ending directly mapped from
85
- # the given parameter. Sinatra's *settings.route* and Soxers
86
- # *settings.origin* are prefixed to the path in order to get an absolute
87
- # filename. If the filename cannot be found, a directory by that name and
88
- # an index file within are probed and read.
89
- #
90
- # If no parameter is given, the entire route is taken as the argument.
91
- def get_page url=params[:splat][0]
92
- out = Urlreader.new
93
- out.url = url
94
- out.get_content
95
+
96
+ module Helpers
97
+ # === The "get_page", the document reading function
98
+ #
99
+ # Read the document in yaml format (with .yaml) ending directly mapped from
100
+ # the given parameter. Sinatra's *settings.route* and Soxers
101
+ # *settings.origin* are prefixed to the path in order to get an absolute
102
+ # filename. If the filename cannot be found, a directory by that name and
103
+ # an index file within are probed and read.
104
+ #
105
+ # If no parameter is given, the entire route is taken as the argument.
106
+ def get_page url=params[:splat][0]
107
+ out = Urlreader.new
108
+ out.url = url
109
+ out.get_content
110
+ end
111
+
112
+ #=== The "get_list" the document listing function
113
+ #
114
+ # The get_list function is the aggregator function. It reads all available
115
+ # yaml files (that map to urls directly) and outputs them according to the
116
+ # arguments you send it. Get_list only accepts a block.
117
+ #==== &block
118
+ # Block is a callback, which filters the entire array of yaml files.
119
+ # The result is an array of hashes, representing a subset of all yaml
120
+ # files from "origin" directory. It can be sorted by using Array.sort
121
+ # method.
122
+ def get_list &block
123
+ pattern = File.join( settings.origin, "**", "*.yaml" )
124
+ output = Dir.glob(pattern).map! do |f|
125
+ file = Filereader.new
126
+ file.filename = f
127
+ if block_given?
128
+ f = block.call file.get_content
129
+ end
130
+ end.compact
131
+ end
132
+
133
+ #=== The "sitemap" the sitemap generator
134
+ #
135
+ # This funnction accepts no arguments. It simply renders a sitemap file
136
+ # with all available urls from the site
137
+ def sitemap
138
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'sitemap.haml' )
139
+ out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
140
+ out << haml( template, :layout => false )
141
+ end
142
+
143
+
144
+ #=== The "atom" the atom feed generator
145
+ #
146
+ # This method accepts an author (which is the global feed's author)
147
+ # This is a required option, as the feed is only valid if it has at least
148
+ # the global author. If individual articles have a yaml field "author",
149
+ # the individual article's author is used for that article. In both cases,
150
+ # author is a hash consisting of values 'name', 'email', 'url', of which
151
+ # at least the 'name' should always be present.
152
+ #
153
+ #==== autor
154
+ # Hash of values as required by the Atom standard:
155
+ # 'name', 'email' and 'url'. Only name is reuired.
156
+ #
157
+ #==== &block
158
+ # Block is a callback. Every file (in hash form) is passed to block and
159
+ # the block acts as the filter. That way only pages which are returned by
160
+ # block are included in the feed
161
+ def atom author=author, &block
162
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'atom.haml' )
163
+ pattern = File.join( settings.origin, "**", "*.yaml" )
164
+ output = Dir.glob(pattern).map! do |f|
165
+ file = Filereader.new
166
+ file.filename = f
167
+ if block_given?
168
+ block.call file.get_content
169
+ end
170
+ end.compact!.sort!{|b,a| a.to_a[0] <=> b.to_a[0] }
171
+ out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
172
+ out << haml( template, :layout => false, :locals => { :page=>get_page, :feed=>output, :author=>author } )
173
+ end
174
+
175
+ def google_ads options={}
176
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'google_ads.haml' )
177
+ pattern = File.join( settings.origin, "**", "*.yaml" )
178
+ haml( template, options.merge!( :layout => false ) )
179
+ end
180
+
181
+ def disqus options={}
182
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'disqus.haml' )
183
+ haml( template, options.merge!( :layout => false ) )
184
+ end
185
+
186
+ def google_analytics options={}
187
+ template = File.read File.join( File.dirname(__FILE__), 'views', 'google_analytics.haml' )
188
+ haml( template, options.merge!( :layout => false ) )
189
+ end
190
+
191
+ #=== "partial" rails like partial generator
192
+ #
193
+ # This funnction accepts a string and matches it to a haml layout (with a
194
+ # underscore prepended) Sinatra's layouts directory.
195
+ #
196
+ #==== snippet
197
+ # A string that maps to a haml view in the views directory
198
+ # "partial :example, :layout => false" would map to a views/_example.haml
199
+ #
200
+ #==== options={}
201
+ # Any options you pass to this partial ger merged and sent to haml as
202
+ # sinatra's haml options (this is usefull for passing sinatra's :layout,
203
+ # :locals and other variables)
204
+ def partial(snippet, options={})
205
+ haml ('_'+snippet.to_s).to_sym, options.merge!(:layout => false)
206
+ end
207
+
208
+ #=== "link_to" rails like link_to generator
209
+ #
210
+ # This funnction accepts a 1 or 2 strings.
211
+ #
212
+ #==== text
213
+ # A string that becomes the link text. If there is no second parameter,
214
+ # link_to converts the string into a local url by replacing all spaces with
215
+ # an underscore and downcasing the string.
216
+ #
217
+ #==== url
218
+ # This string is used for 'href' in a link
219
+ def link_to(text, url="/#{text.downcase.gsub(/\s/,'_')}")
220
+ url.gsub!(/^\//, '') if url =~ /.+:\/\//
221
+ "<a href=\"#{url}\"> #{text}</a>"
222
+ end
223
+
224
+ # A simple string obuscator.
225
+ # Useful for hiding emails and such
226
+ #=== "obfuscate" simple string obuscator.
227
+ #
228
+ # This funnction accepts a 1 or 2 strings.
229
+ #
230
+ #==== str=nil
231
+ # Obfuscates a string replacing characters with html entities.
232
+ # Useful for hiding emails and such
233
+ def obfuscate(str=nil)
234
+ out = []
235
+ str.each_byte {|c| out << "&##{c};" }
236
+ out.join
237
+ end
238
+
95
239
  end
96
-
97
- #=== The "get_list" the document listing function
98
- #
99
- # The get_list function is the aggregator function. It reads all available
100
- # yaml files (that map to urls directly) and outputs them according to the
101
- # arguments you send it. Get_list only accepts 1 argument and a block.
102
- #
103
- #==== sort='desc'
104
- # Direction of output. 'desc' (descending) or 'asc' (ascending)The default
105
- # is 'desc'. If :sort conatins anything else, the output is unsorted.
106
- #
107
- #==== &block
108
- # Block is a callback. Every file (in hash form) is passed to block and
109
- # the block acts as the filter. :sort only takes the result and sorts it
110
- # according to the first key/value pair, so hash order IS signifficant.
111
- def get_list sort='desc', &block
112
- pattern = File.join( settings.root, settings.origin, "**", "*.yaml" )
113
- output = Dir.glob(pattern).map! do |f|
114
- file = Filereader.new
115
- file.filename = f
116
- if block_given?
117
- f = block.call file.get_content
240
+
241
+ def self.registered(app)
242
+ app.helpers Soxer::Helpers
243
+
244
+ def app.settings
245
+ Sinatra::Application
246
+ end
247
+
248
+ set :origin, File.join(app.settings.root, 'content')
249
+
250
+ app.get("/sitemap.xml") { sitemap }
251
+
252
+ app.get "/*.css" do
253
+ content_type "text/css", :charset => "utf-8"
254
+ sass params[:splat][0].to_sym
255
+ end
256
+
257
+ app.get '*.*' do
258
+ file = File.join( settings.origin, params[:splat].join('.') )
259
+ case params[:splat][1]
260
+ when /[jpg|png|pdf|doc|docx|xls|xlsx|pdf|]/i then send_file(file, :disposition => nil)
118
261
  end
119
- end.compact
120
- case sort
121
- when 'desc' then output.sort!{|b,a| a.to_a[0] <=> b.to_a[0] }
122
- when 'asc' then output.sort!{|a,b| a.to_a[0] <=> b.to_a[0] }
123
262
  end
124
- end
125
-
126
- #=== The "sitemap" the sitemap generator
127
- #
128
- # This funnction accepts no arguments. It simply renders a sitemap file
129
- # with all available urls from the site
130
- def sitemap
131
- template = File.read File.join( File.dirname(__FILE__), 'views', 'sitemap.haml' )
132
- out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
133
- out << haml( template, :layout => false )
134
- end
135
-
136
-
137
- #=== The "atom" the atom feed generator
138
- #
139
- # This method accepts an author (which is the global feed's author)
140
- # This is a required option, as the feed is only valid if it has at least
141
- # the global author. If individual articles have a yaml field "author",
142
- # the individual article's author is used for that article. In both cases,
143
- # author is a hash consisting of values 'name', 'email', 'url', of which
144
- # at least the 'name' should always be present.
145
- #
146
- #==== autor
147
- # Hash of values as required by the Atom standard:
148
- # 'name', 'email' and 'url'. Only name is reuired.
149
- #
150
- #==== &block
151
- # Block is a callback. Every file (in hash form) is passed to block and
152
- # the block acts as the filter. That way only pages which are returned by
153
- # block are included in the feed
154
- def atom author=author, &block
155
- template = File.read File.join( File.dirname(__FILE__), 'views', 'atom.haml' )
156
- pattern = File.join( settings.root, settings.origin, "**", "*.yaml" )
157
- output = Dir.glob(pattern).map! do |f|
158
- file = Filereader.new
159
- file.filename = f
160
- if block_given?
161
- block.call file.get_content
263
+
264
+ app.get '*/?' do
265
+ content_type "text/html", :charset => "utf-8"
266
+
267
+ if params[:splat].last =~ /\.atom$/ then
268
+ set :haml, { :format => :xhtml }
269
+ content_type "application/atom+xml", :charset => "utf-8"
162
270
  end
163
- end.compact!.sort!{|b,a| a.to_a[0] <=> b.to_a[0] }
164
- out = '<?xml version="1.0" encoding="UTF-8"?>'+"\n"
165
- out << haml( template, :layout => false, :locals => { :page=>get_page, :feed=>output, :author=>author } )
166
- end
167
-
168
- def google_ads options={}
169
- template = File.read File.join( File.dirname(__FILE__), 'views', 'google_ads.haml' )
170
- pattern = File.join( settings.root, settings.origin, "**", "*.yaml" )
171
- haml( template, options.merge!( :layout => false ) )
172
- end
173
-
174
- def disqus options={}
175
- template = File.read File.join( File.dirname(__FILE__), 'views', 'disqus.haml' )
176
- haml( template, options.merge!( :layout => false ) )
177
- end
178
-
179
- def google_analytics options={}
180
- template = File.read File.join( File.dirname(__FILE__), 'views', 'google_analytics.haml' )
181
- haml( template, options.merge!( :layout => false ) )
182
- end
183
-
184
- #=== "partial" rails like partial generator
185
- #
186
- # This funnction accepts a string and matches it to a haml layout (with a
187
- # underscore prepended) Sinatra's layouts directory.
188
- #
189
- #==== snippet
190
- # A string that maps to a haml view in the views directory
191
- # "partial :example, :layout => false" would map to a views/_example.haml
192
- #
193
- #==== options={}
194
- # Any options you pass to this partial ger merged and sent to haml as
195
- # sinatra's haml options (this is usefull for passing sinatra's :layout,
196
- # :locals and other variables)
197
- def partial(snippet, options={})
198
- haml ('_'+snippet).to_sym, options.merge!(:layout => false)
199
- end
200
-
201
- #=== "link_to" rails like link_to generator
202
- #
203
- # This funnction accepts a 1 or 2 strings.
204
- #
205
- #==== text
206
- # A string that becomes the link text. If there is no second parameter,
207
- # link_to converts the string into a local url by replacing all spaces with
208
- # an underscore and downcasing the string.
209
- #
210
- #==== url
211
- # This string is used for 'href' in a link
212
- def link_to(text, url="/#{text.downcase.gsub(/\s/,'_')}")
213
- url.gsub!(/^\//, '') if url =~ /.+:\/\//
214
- "<a href=\"#{url}\"> #{text}</a>"
215
- end
216
-
217
- # A simple string obuscator.
218
- # Useful for hiding emails and such
219
- #=== "obfuscate" simple string obuscator.
220
- #
221
- # This funnction accepts a 1 or 2 strings.
222
- #
223
- #==== str=nil
224
- # Obfuscates a string replacing characters with html entities.
225
- # Useful for hiding emails and such
226
- def obfuscate(str=nil)
227
- out = []
228
- str.each_byte {|c| out << "&##{c};" }
229
- out.join
271
+
272
+ page = get_page
273
+ page['layout'] ||= 'layout'
274
+ haml page['content'], :layout => page['layout'].to_sym, :locals => { :page => page }
275
+ end
230
276
  end
231
-
232
277
  end
233
-
234
- helpers Soxer
278
+
279
+ register Soxer
235
280
  end
281
+
@@ -5,9 +5,9 @@ require "app"
5
5
  disable :run
6
6
  set :server, %w[thin mongrel webrick]
7
7
  set :origin, "content"
8
- set :haml, {:encoding => 'utf-8',
9
- :format => :html5,
10
- :attr_wrapper => '"' }
8
+ set :haml, {:format => :html5,
9
+ :attr_wrapper => '"'}
10
+ set :haml, {:encoding => 'utf-8'} if RUBY_VERSION=~/1\.9/
11
11
 
12
12
  configure :development do
13
13
  require 'sinatra/reloader'
@@ -15,6 +15,7 @@ configure :development do
15
15
  end
16
16
 
17
17
  configure :production do
18
+ set :haml, {:ugly => true}
18
19
  set :port, 55500
19
20
  end
20
21
 
data/soxer.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.7'
5
5
 
6
6
  s.name = 'soxer'
7
- s.version = '0.9.4'
8
- s.date = '2010-10-27'
7
+ s.version = '0.9.5'
8
+ s.date = '2010-11-01'
9
9
  s.rubyforge_project = 'soxer'
10
10
 
11
11
  s.summary = "Dynamic web site generator engine"
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  # = MANIFEST =
28
28
  s.files = %w[
29
29
  soxer.gemspec
30
+ CHANGES
30
31
  bin/soxer
31
32
  lib/soxer.rb
32
33
  lib/soxer/main.rb
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soxer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 51
4
+ hash: 49
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 4
10
- version: 0.9.4
9
+ - 5
10
+ version: 0.9.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Toni Anzlovar
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-27 00:00:00 +02:00
18
+ date: 2010-11-01 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -70,6 +70,7 @@ extra_rdoc_files: []
70
70
 
71
71
  files:
72
72
  - soxer.gemspec
73
+ - CHANGES
73
74
  - bin/soxer
74
75
  - lib/soxer.rb
75
76
  - lib/soxer/main.rb