smeagol 0.2.1 → 0.2.2

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.
data/bin/smeagol CHANGED
@@ -9,6 +9,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../lib/smeagol')
9
9
  options = OpenStruct.new
10
10
  options.port = 4567
11
11
  options.auto_update = false
12
+ options.cache_enabled = true
12
13
  opts = OptionParser.new do |opts|
13
14
  opts.banner = 'usage: smeagol [OPTIONS] [PATH]\n\n'
14
15
 
@@ -24,6 +25,10 @@ opts = OptionParser.new do |opts|
24
25
  options.auto_update = flag
25
26
  end
26
27
 
28
+ opts.on('--[no-]cache', 'Enables page caching.') do |flag|
29
+ options.cache_enabled = flag
30
+ end
31
+
27
32
  opts.on('-v', '--version', 'Display current version.') do
28
33
  puts "Smeagol #{Smeagol::VERSION}"
29
34
  exit 0
@@ -68,8 +73,12 @@ if options.git && options.auto_update
68
73
  end
69
74
  end
70
75
 
76
+ # Clear the cache
77
+ Smeagol::Cache.new(Gollum::Wiki.new(gollum_path)).clear()
78
+
71
79
  # Run the web server
72
80
  Smeagol::App.set(:gollum_path, gollum_path)
73
81
  Smeagol::App.set(:git, options.git)
82
+ Smeagol::App.set(:cache_enabled, options.cache_enabled)
74
83
  Smeagol::App.run!(:port => options.port)
75
84
 
data/lib/file.rb ADDED
@@ -0,0 +1,10 @@
1
+ class File
2
+ # Removes all references to parent directories (../) in a path.
3
+ #
4
+ # path - The path to sanitize.
5
+ #
6
+ # Returns a clean, pristine path.
7
+ def self.sanitize_path(path)
8
+ path.gsub(/\.\.(?=$|\/)/, '') unless path.nil?
9
+ end
10
+ end
data/lib/smeagol.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  $:.unshift(File.dirname(__FILE__))
2
+ require 'file'
3
+
2
4
  require 'smeagol/app'
5
+ require 'smeagol/cache'
3
6
  require 'smeagol/hash'
4
7
  require 'smeagol/updater'
5
8
  require 'smeagol/wiki'
data/lib/smeagol/app.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'gollum'
2
2
  require 'sinatra'
3
3
  require 'mustache'
4
+ require 'tmpdir'
4
5
  require 'smeagol/views/page'
5
6
 
6
7
  module Smeagol
@@ -33,13 +34,24 @@ module Smeagol
33
34
  get '/*' do
34
35
  name = params[:splat].first
35
36
  name = "Home" if name == ""
37
+ name = File.sanitize_path(name)
36
38
 
37
39
  # Load the wiki settings
38
40
  wiki = Smeagol::Wiki.new(settings.gollum_path)
39
- if page = wiki.page(name)
40
- Mustache.render(page_template, Smeagol::Views::Page.new(page))
41
+ cache = Smeagol::Cache.new(wiki)
42
+
43
+ # First check the cache
44
+ if settings.cache_enabled && cache.cache_hit?(name)
45
+ cache.get_page(name)
46
+ # Then try to create the wiki page
47
+ elsif page = wiki.page(name)
48
+ content = Mustache.render(page_template, Smeagol::Views::Page.new(page))
49
+ cache.set_page(name, content) if settings.cache_enabled
50
+ content
51
+ # If it is not a wiki page then try to find the file
41
52
  elsif file = wiki.file(name)
42
53
  file.raw_data
54
+ # Otherwise return a 404 error
43
55
  else
44
56
  raise Sinatra::NotFound
45
57
  end
@@ -0,0 +1,84 @@
1
+ require 'fileutils'
2
+
3
+ module Smeagol
4
+ class Cache
5
+ # Creates a cache object for a Gollum wiki.
6
+ #
7
+ # wiki - The wiki to cache.
8
+ #
9
+ # Returns a Smeagol::Cache object.
10
+ def initialize(wiki)
11
+ @wiki = wiki
12
+ @path = "#{Dir.tmpdir}/smeagol/#{File.expand_path(@wiki.path)}"
13
+ end
14
+
15
+ # The cached wiki.
16
+ attr_reader :wiki
17
+
18
+ # The path to the smeagol cache for this wiki.
19
+ attr_accessor :path
20
+
21
+
22
+ # Clears the entire cache.
23
+ def clear
24
+ FileUtils.rm_rf(path)
25
+ end
26
+
27
+ # Checks if a cache hit is found for a given gollum page.
28
+ #
29
+ # name - The name of the page to check.
30
+ #
31
+ # Returns true if the page has been cached, otherwise returns false.
32
+ def cache_hit?(name)
33
+ page = wiki.page(name)
34
+ File.exists?(page_path(name)) unless page.nil?
35
+ end
36
+
37
+ # Retrieves the content of the cached page.
38
+ #
39
+ # name - The name of the wiki page.
40
+ #
41
+ # Returns the contents of the HTML page if cached. Otherwise returns nil.
42
+ def get_page(name)
43
+ IO.read(page_path(name)) if cache_hit?(name)
44
+ end
45
+
46
+ # Sets the cached content for a page.
47
+ #
48
+ # name - The name of the wiki page.
49
+ # content - The content to cache.
50
+ #
51
+ # Returns nothing.
52
+ def set_page(name, content)
53
+ page = wiki.page(name)
54
+ if !page.nil?
55
+ FileUtils.mkdir_p(File.dirname(page_path(name)))
56
+ File.open(page_path(name), 'w') do |f|
57
+ f.write(content)
58
+ end
59
+ end
60
+ end
61
+
62
+ # Removes the cached content for a page.
63
+ #
64
+ # name - The name of the wiki page.
65
+ #
66
+ # Returns nothing.
67
+ def remove_page(name)
68
+ page = wiki.page(name)
69
+ File.delete(page_path(name)) if !page.nil? && File.exists?(page_path(name))
70
+ end
71
+
72
+ # Retrieves the path to the cache for a given page.
73
+ #
74
+ # name - The name of the wiki page.
75
+ #
76
+ # Returns a file path to the cached wiki page.
77
+ def page_path(name)
78
+ page = wiki.page(name)
79
+ if !page.nil?
80
+ "#{path}/#{page.path}/#{page.version}"
81
+ end
82
+ end
83
+ end
84
+ end
@@ -1,3 +1,3 @@
1
1
  module Smeagol
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -45,7 +45,7 @@ module Smeagol
45
45
  page.title != "Home"
46
46
  end
47
47
 
48
- # Public: The HTML menu generated from the settings.yaml file.
48
+ # Public: The HTML menu generated from the settings.yml file.
49
49
  def menu_html
50
50
  menu = @page.wiki.settings.menu
51
51
  if !menu.nil?
data/lib/smeagol/wiki.rb CHANGED
@@ -17,7 +17,7 @@ module Smeagol
17
17
  def settings
18
18
  # Cache settings if already read
19
19
  if @settings.nil?
20
- file = "#{path}/settings.yaml"
20
+ file = "#{path}/settings.yml"
21
21
  if File.readable?(file)
22
22
  @settings = YAML::load(IO.read(file)).to_ostruct
23
23
  else
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require 'fileutils'
3
+
4
+ class CacheTestCase < MiniTest::Unit::TestCase
5
+ def setup
6
+ @wiki = Smeagol::Wiki.new(ENV['SMEAGOL_TEST_WIKI_PATH'])
7
+ @cache = Smeagol::Cache.new(@wiki)
8
+ @cache.clear()
9
+ end
10
+
11
+ def test_should_show_cache_hit
12
+ @cache.set_page('Home', 'abc')
13
+ assert @cache.cache_hit?('Home')
14
+ end
15
+
16
+ def test_should_show_cache_miss
17
+ assert !@cache.cache_hit?('Home')
18
+ end
19
+
20
+ def test_should_show_cache_miss_for_nonexistent_page
21
+ assert !@cache.cache_hit?('THIS_IS_NOT_A_PAGE!')
22
+ end
23
+
24
+ def test_should_cache_page
25
+ @cache.set_page('Home', 'abc')
26
+ assert_equal 'abc', @cache.get_page('Home')
27
+ end
28
+
29
+ def test_should_remove_cache
30
+ @cache.set_page('Home', 'abc')
31
+ @cache.remove_page('Home')
32
+ assert !@cache.cache_hit?('Home')
33
+ end
34
+ end
data/test/test_file.rb ADDED
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class FileTestCase < MiniTest::Unit::TestCase
4
+ def test_sanitize_should_remove_parent_refs
5
+ assert_equal '/', File.sanitize_path('../')
6
+ assert_equal '/', File.sanitize_path('/..')
7
+ assert_equal '//', File.sanitize_path('/../')
8
+ assert_equal '', File.sanitize_path('..')
9
+ assert_equal '..abc', File.sanitize_path('..abc')
10
+ assert_equal '/this/is//a/test', File.sanitize_path('/this/is/../a/test')
11
+ end
12
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smeagol
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 1
10
- version: 0.2.1
9
+ - 2
10
+ version: 0.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ben Johnson
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-23 00:00:00 -06:00
18
+ date: 2010-09-24 00:00:00 -06:00
19
19
  default_executable: smeagol
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -247,7 +247,9 @@ extensions: []
247
247
  extra_rdoc_files: []
248
248
 
249
249
  files:
250
+ - lib/file.rb
250
251
  - lib/smeagol/app.rb
252
+ - lib/smeagol/cache.rb
251
253
  - lib/smeagol/hash.rb
252
254
  - lib/smeagol/public/smeagol/main.css
253
255
  - lib/smeagol/public/smeagol/pygment.css
@@ -259,6 +261,8 @@ files:
259
261
  - lib/smeagol.rb
260
262
  - README.md
261
263
  - test/helper.rb
264
+ - test/test_cache.rb
265
+ - test/test_file.rb
262
266
  - test/test_hash.rb
263
267
  - test/test_wiki.rb
264
268
  - bin/smeagol
@@ -298,5 +302,7 @@ specification_version: 3
298
302
  summary: A read-only server for Gollum wikis
299
303
  test_files:
300
304
  - test/helper.rb
305
+ - test/test_cache.rb
306
+ - test/test_file.rb
301
307
  - test/test_hash.rb
302
308
  - test/test_wiki.rb