kinbote 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/CHANGES +0 -0
  2. data/LICENSE +22 -0
  3. data/README.rdoc +19 -0
  4. data/Rakefile +64 -0
  5. data/bin/kinbote +13 -0
  6. data/kinbote.gemspec +75 -0
  7. data/lib/kinbote.rb +5 -0
  8. data/lib/kinbote/attribute.rb +71 -0
  9. data/lib/kinbote/base.rb +19 -0
  10. data/lib/kinbote/page.rb +189 -0
  11. data/lib/kinbote/page_match.rb +12 -0
  12. data/lib/kinbote/site.rb +175 -0
  13. data/lib/kinbote/util.rb +48 -0
  14. data/lib/kinbote/value.rb +45 -0
  15. data/lib/sinatra/kinbote.rb +115 -0
  16. data/lib/sinatra/kinbote_helpers.rb +63 -0
  17. data/site/.kinbote/views/attributes.haml +19 -0
  18. data/site/.kinbote/views/examples/header.haml +12 -0
  19. data/site/.kinbote/views/examples/home.haml +40 -0
  20. data/site/.kinbote/views/examples/page_attributes.haml +1 -0
  21. data/site/.kinbote/views/examples/page_attributes_title.haml +2 -0
  22. data/site/.kinbote/views/examples/related.haml +16 -0
  23. data/site/.kinbote/views/examples/related2.haml +8 -0
  24. data/site/.kinbote/views/examples/related_any.haml +8 -0
  25. data/site/.kinbote/views/examples/specific.haml +3 -0
  26. data/site/.kinbote/views/layout.haml +14 -0
  27. data/site/.kinbote/views/page.haml +18 -0
  28. data/site/.kinbote/views/pages.haml +26 -0
  29. data/site/.kinbote/views/site.haml +4 -0
  30. data/site/config/site.yml +1 -0
  31. data/site/kinbote-server +15 -0
  32. data/site/public/favicon.ico +0 -0
  33. data/site/public/js/core.js +2 -0
  34. data/site/public/js/jquery.js +19 -0
  35. data/site/public/robots.txt +1 -0
  36. data/site/views/404.haml +1 -0
  37. data/site/views/500.haml +1 -0
  38. data/site/views/index.haml +1 -0
  39. data/site/views/layout.haml +21 -0
  40. data/site/views/sass/core.sass +14 -0
  41. data/site/views/snippets/sample.haml +4 -0
  42. metadata +130 -0
data/CHANGES ADDED
File without changes
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010 Jay Boice
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = Kinbote
2
+
3
+ Kinbote publishes.
4
+
5
+ Install the gem:
6
+
7
+ sudo gem install kinbote
8
+
9
+ Create a new kinbote project and start the local server:
10
+
11
+ kinbote mysite
12
+ cd mysite
13
+ ./kinbote-server
14
+
15
+ Open the local site in your browser at http://localhost:4567
16
+
17
+ Add pages to your site at http://localhost:4567/kinbote/pages
18
+
19
+
@@ -0,0 +1,64 @@
1
+ require 'rake/clean'
2
+ require 'rake/testtask'
3
+ require 'fileutils'
4
+ require 'date'
5
+
6
+ task :default => :test
7
+ task :spec => :test
8
+
9
+ def source_version
10
+ line = File.read('lib/kinbote/base.rb')[/^\s*VERSION = .*/]
11
+ line.match(/.*VERSION = '(.*)'/)[1]
12
+ end
13
+
14
+ # PACKAGING ============================================================
15
+
16
+ if defined?(Gem)
17
+ # Load the gemspec using the same limitations as github
18
+ def spec
19
+ require 'rubygems' unless defined? Gem::Specification
20
+ @spec ||= eval(File.read('kinbote.gemspec'))
21
+ end
22
+
23
+ def package(ext='')
24
+ "pkg/kinbote-#{spec.version}" + ext
25
+ end
26
+
27
+ desc 'Build packages'
28
+ task :package => %w[.gem].map {|e| package(e)}
29
+
30
+ desc 'Build and install as local gem'
31
+ task :install => package('.gem') do
32
+ sh "gem install #{package('.gem')}"
33
+ end
34
+
35
+ directory 'pkg/'
36
+ CLOBBER.include('pkg')
37
+
38
+ file package('.gem') => %w[pkg/ kinbote.gemspec] + spec.files do |f|
39
+ sh "gem build kinbote.gemspec"
40
+ mv File.basename(f.name), f.name
41
+ end
42
+
43
+ task 'kinbote.gemspec' => FileList['{lib,site}/**','Rakefile','CHANGES','LICENSE','*.rdoc'] do |f|
44
+ # read spec file and split out manifest section
45
+ spec = File.read(f.name)
46
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
47
+ # replace version and date
48
+ head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
49
+ head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
50
+ # determine file list from git ls-files
51
+ files = `git ls-files`.
52
+ split("\n").
53
+ sort.
54
+ reject{ |file| file =~ /^\./ }.
55
+ reject { |file| file =~ /^doc/ }.
56
+ map{ |file| " #{file}" }.
57
+ join("\n")
58
+ # piece file back together and write...
59
+ manifest = " s.files = %w[\n#{files}\n ]\n"
60
+ spec = [head,manifest,tail].join(" # = MANIFEST =\n")
61
+ File.open(f.name, 'w') { |io| io.write(spec) }
62
+ puts "updated #{f.name}"
63
+ end
64
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+
4
+ name = ARGV[0]
5
+
6
+ puts "Creating a kinbote site in '#{name}'..."
7
+
8
+ if File.exists?(name)
9
+ $stderr.puts "A site with name '#{name}' already exists in this directory."
10
+ exit 1
11
+ end
12
+
13
+ FileUtils.copy_entry("#{File.dirname(__FILE__)}/../site", name)
@@ -0,0 +1,75 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
+
5
+ s.name = 'kinbote'
6
+ s.version = '0.0.1'
7
+ s.date = '2010-07-10'
8
+
9
+ s.description = "Kinbote"
10
+ s.summary = "Kinbote"
11
+
12
+ s.authors = ["Jay Boice"]
13
+ s.email = "jboice@gmail.com"
14
+
15
+ # = MANIFEST =
16
+ s.files = %w[
17
+ CHANGES
18
+ LICENSE
19
+ README.rdoc
20
+ Rakefile
21
+ bin/kinbote
22
+ kinbote.gemspec
23
+ lib/kinbote.rb
24
+ lib/kinbote/attribute.rb
25
+ lib/kinbote/base.rb
26
+ lib/kinbote/page.rb
27
+ lib/kinbote/page_match.rb
28
+ lib/kinbote/site.rb
29
+ lib/kinbote/util.rb
30
+ lib/kinbote/value.rb
31
+ lib/sinatra/kinbote.rb
32
+ lib/sinatra/kinbote_helpers.rb
33
+ site/.kinbote/views/attributes.haml
34
+ site/.kinbote/views/examples/header.haml
35
+ site/.kinbote/views/examples/home.haml
36
+ site/.kinbote/views/examples/page_attributes.haml
37
+ site/.kinbote/views/examples/page_attributes_title.haml
38
+ site/.kinbote/views/examples/related.haml
39
+ site/.kinbote/views/examples/related2.haml
40
+ site/.kinbote/views/examples/related_any.haml
41
+ site/.kinbote/views/examples/specific.haml
42
+ site/.kinbote/views/layout.haml
43
+ site/.kinbote/views/page.haml
44
+ site/.kinbote/views/pages.haml
45
+ site/.kinbote/views/site.haml
46
+ site/config/site.yml
47
+ site/kinbote-server
48
+ site/public/favicon.ico
49
+ site/public/js/core.js
50
+ site/public/js/jquery.js
51
+ site/public/robots.txt
52
+ site/views/404.haml
53
+ site/views/500.haml
54
+ site/views/index.haml
55
+ site/views/layout.haml
56
+ site/views/sass/core.sass
57
+ site/views/snippets/sample.haml
58
+ ]
59
+ # = MANIFEST =
60
+
61
+ s.default_executable = 'kinbote'
62
+ s.executables = [ 'kinbote' ]
63
+ s.require_paths = [ 'lib' ]
64
+
65
+ s.extra_rdoc_files = %w[README.rdoc LICENSE]
66
+ s.add_dependency 'sinatra', '>= 1.0'
67
+ s.add_dependency 'haml', '>= 3.0.13'
68
+ s.add_dependency 'net-scp'
69
+
70
+ s.has_rdoc = true
71
+ s.homepage = "http://github.com/jayb/kinbote"
72
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Kinbote", "--main", "README.rdoc"]
73
+ s.require_paths = %w[lib]
74
+ s.rubygems_version = '1.1.1'
75
+ end
@@ -0,0 +1,5 @@
1
+ libdir = "#{File.dirname(__FILE__)}"
2
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
+
4
+ require 'kinbote/base'
5
+ require 'sinatra/kinbote'
@@ -0,0 +1,71 @@
1
+ module Kinbote
2
+ class Attribute
3
+ include Util
4
+
5
+ attr_accessor :name, :values, :_varname
6
+
7
+ def initialize(name, page, values, global_attribute = nil)
8
+ @name = name.to_s
9
+ @pages = []
10
+ @values = []
11
+ @global_attribute = global_attribute || self
12
+ add_page(page, values)
13
+ @_varname = slugify(@name).gsub("-", "_")
14
+ @css = File.exist?(file_name(:css))
15
+ end
16
+
17
+ def add_page(page, values)
18
+ @pages.delete_if{|p| p.slug == page.slug}
19
+ @pages << page
20
+ values.each do |v|
21
+ g_val = $site.find_value(v, @global_attribute, true)
22
+ if g_val
23
+ g_val.add_page(page)
24
+ else
25
+ g_val = Value.new(v, page, @global_attribute)
26
+ $site.add_value(g_val)
27
+ end
28
+ l_val = $site.find_value(v, self)
29
+ if l_val
30
+ l_val.add_page(page)
31
+ else
32
+ @values << Value.new(v, page, @global_attribute, g_val)
33
+ end
34
+ end
35
+ end
36
+
37
+ def remove_page(page)
38
+ @values.map{|value| value.remove_page(page)}
39
+ @global_attribute.pages.delete_if{|p| p.slug == page.slug}
40
+ @pages.delete_if{|p| p.slug == page.slug}
41
+ @global_attribute.values.delete_if{|v| v.pages.size == 0}
42
+ @values.delete_if{|v| v.pages.size == 0}
43
+ end
44
+
45
+ def create_css
46
+ FileUtils.mkdir_p(file_name(:css, true)) if !File.exist?(file_name(:css, true))
47
+ File.open(file_name(:css), "w") if !File.exist?(file_name(:css))
48
+ @global_attribute.css!
49
+ end
50
+
51
+ def file_name(type, dir = nil)
52
+ if type == :css
53
+ return "#{$site.kinbote_path}/views/sass/attributes/#{@name}/#{!dir ? "_all.sass" : ""}"
54
+ end
55
+ end
56
+
57
+ def css_files
58
+ files = (@global_attribute.css? ? ["/css/attributes/#{@name}/_all"] : [])
59
+ @values.each do |value|
60
+ files += value.css_files
61
+ end
62
+ files
63
+ end
64
+
65
+ def pages; @global_attribute == self ? @pages : @global_attribute.pages; end
66
+ def to_s; @name; end
67
+ def css!; @global_attribute == self ? @css = true : @global_attribute.css!; end
68
+ def css?; @global_attribute == self ? @css : @global_attribute.css?; end
69
+
70
+ end
71
+ end
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ require 'haml'
4
+ require 'sass'
5
+ require 'ftools'
6
+ require 'fileutils'
7
+ require 'net/ssh'
8
+ require 'net/scp'
9
+
10
+ require 'kinbote/util'
11
+ require 'kinbote/site'
12
+ require 'kinbote/page'
13
+ require 'kinbote/attribute'
14
+ require 'kinbote/value'
15
+ require 'kinbote/page_match'
16
+
17
+ module Kinbote
18
+ VERSION = '0.0.1'
19
+ end
@@ -0,0 +1,189 @@
1
+ module Kinbote
2
+ class Page
3
+ include Util
4
+
5
+ attr_accessor :title, :attributes, :slug
6
+
7
+ def initialize(title, file=nil, attributes=nil)
8
+ @title = title
9
+ @directory = (file ? dir_from_file(file) : file_path(:html, true))
10
+ @file = file || file_path(:html)
11
+ @slug = slug_from_file(@file)
12
+ @attributes = []
13
+ add_attributes(attributes || {"Date" => Time.now.strftime("%B %d, %Y")})
14
+ create_html
15
+ @css = File.exist?(file_path(:css))
16
+ set_ivars
17
+ end
18
+
19
+ def set_attributes(attributes)
20
+ new_title = remove_title(attributes)
21
+ return if same_attributes(attributes, new_title)
22
+ @title = new_title if new_title && new_title.size > 0
23
+ $site.remove_page_attributes(self)
24
+ @attributes.map{|att| att.remove_page(self)}
25
+ @attributes.delete_if{|att| att.pages.size == 0}
26
+ @attributes = []
27
+ add_attributes(attributes)
28
+ $site.add_kinbote_haml(self)
29
+ set_ivars
30
+ end
31
+
32
+ def loosely_related_pages(attribute_names = nil)
33
+ page_matches = []
34
+ if !attribute_names
35
+ page_matches += loosely_related_pages(@attributes.map{|a| a.name})
36
+ elsif attribute_names.is_a?(Array)
37
+ attribute_names.each do |a_name|
38
+ page_matches += lrp(a_name)
39
+ end
40
+ else
41
+ page_matches += lrp(attribute_names)
42
+ end
43
+ page_matches.uniq
44
+ end
45
+
46
+ def strongly_related_pages(attribute_names = nil, values = nil)
47
+ page_matches = []
48
+ if !attribute_names
49
+ page_matches += strongly_related_pages(@attributes.map{|a| a.name})
50
+ elsif attribute_names.is_a?(Array)
51
+ attribute_names.each do |a_name|
52
+ page_matches += srp(a_name, values)
53
+ end
54
+ else
55
+ page_matches += srp(attribute_names, values)
56
+ end
57
+ page_matches.uniq
58
+ end
59
+
60
+ def values
61
+ vals = []
62
+ @attributes.each do |a|
63
+ a.values.each do |v|
64
+ vals << v
65
+ end
66
+ end
67
+ vals
68
+ end
69
+
70
+ def delete_files
71
+ FileUtils.rm_f(file_path(:css))
72
+ FileUtils.rm_f(file_path(:html))
73
+ end
74
+
75
+ def path
76
+ path = []
77
+ in_path = false
78
+ @directory.split("/").each do |d|
79
+ in_path = true if d == "pages"
80
+ path << d if in_path
81
+ end
82
+ "#{path.join("/")}/#{@slug}"
83
+ end
84
+
85
+ def create_css
86
+ FileUtils.mkdir_p(file_path(:css, true)) if !File.exist?(file_path(:css, true))
87
+ File.open(file_path(:css), "w") if !File.exist?(file_path(:css))
88
+ @css = true
89
+ end
90
+
91
+ def css_files
92
+ files = (css? ? ["/css/pages/#{@slug}"] : [])
93
+ @attributes.each do |attribute|
94
+ files += attribute.css_files
95
+ end
96
+ files
97
+ end
98
+
99
+ def file_path(type, dir = nil)
100
+ if type == :html
101
+ return @file if @file && !dir
102
+ return @directory if @directory && dir
103
+ return "#{$site.kinbote_path}/views/pages/#{Time.now.strftime("%Y/%m")}/#{!dir ? "/#{slugify(@title)}.haml" : ""}"
104
+ elsif type == :css
105
+ return "#{@directory}#{!dir ? "#{@slug}.sass" : ""}"
106
+ end
107
+ end
108
+
109
+ def set_filesize; @filesize = File.size(file_path(:html)); end
110
+ def get_filesize; @filesize; end
111
+ def to_s; @title; end
112
+ def css!; @css = true; end
113
+ def css?; @css; end
114
+ def url; "#{@slug}.html"; end
115
+
116
+ private
117
+
118
+ def remove_title(attributes)
119
+ new_title = nil
120
+ title_keys = []
121
+ attributes.each do |key, value|
122
+ if key.downcase == "title"
123
+ new_title = value if !new_title
124
+ title_keys << key
125
+ end
126
+ end
127
+ attributes.delete_if{|key, value| title_keys.include?(key)}
128
+ new_title.first
129
+ end
130
+
131
+ def create_html
132
+ FileUtils.mkdir_p(file_path(:html, true)) if !File.exist?(file_path(:html, true))
133
+ if !File.exist?(file_path(:html))
134
+ File.open(file_path(:html), "w")
135
+ $site.add_kinbote_haml(self)
136
+ end
137
+ end
138
+
139
+ def set_ivars
140
+ @attributes.each do |att|
141
+ instance_variable_set("@#{att._varname}", att.values)
142
+ Page.send(:define_method, att._varname.to_sym, Proc.new{ eval("@#{att._varname}") }) if !Page.respond_to?(att._varname)
143
+ end
144
+ end
145
+
146
+ def same_attributes(attributes, new_title)
147
+ return false if !new_title || new_title.size == 0 || new_title != @title
148
+ @attributes.sort_by{|a| a.name}.map{|a| "#{a.name}#{a.values.sort_by{|v| v.value}.map{|v| v.value}.join}"}.join == attributes.to_a.sort_by{|a| a.first}.map{|a| "#{a.first}#{a.last.sort.join}"}.join
149
+ end
150
+
151
+ def add_attributes(attributes)
152
+ attributes.each do |name, values|
153
+ g_att = $site.find_attribute(name)
154
+ if g_att
155
+ g_att.add_page(self, values)
156
+ else
157
+ g_att = Attribute.new(name, self, values)
158
+ $site.add_attribute(g_att)
159
+ end
160
+ l_att = $site.find_attribute(name, self)
161
+ if l_att
162
+ l_att.add_page(self, values)
163
+ else
164
+ @attributes << Attribute.new(name, self, values, g_att)
165
+ end
166
+ end
167
+ end
168
+
169
+ def srp(attribute_name, values)
170
+ page_matches = []
171
+ l_att = $site.find_attribute(attribute_name, self)
172
+ g_att = $site.find_attribute(attribute_name)
173
+ return page_matches if !l_att || !g_att
174
+ l_att.values.each do |val|
175
+ next if values && values.size > 0 && !values.include?(val.value)
176
+ g_val = $site.find_value(val.value, g_att, true)
177
+ page_matches += (g_val.pages - [self]).map{|p| PageMatch.new(p, g_att, g_val)}
178
+ end
179
+ page_matches
180
+ end
181
+
182
+ def lrp(attribute_name)
183
+ g_att = $site.find_attribute(attribute_name)
184
+ return [] if !g_att || g_att.name.downcase == "date"
185
+ (g_att.pages - [self]).map{|p| PageMatch.new(p, g_att)}
186
+ end
187
+
188
+ end
189
+ end