eduardo-vanilla 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/README +53 -0
  2. data/Rakefile +121 -0
  3. data/bin/vanilla +9 -0
  4. data/config.example.yml +5 -0
  5. data/config.ru +9 -0
  6. data/lib/defensio.rb +59 -0
  7. data/lib/tasks/vanilla.rake +178 -0
  8. data/lib/vanilla.rb +20 -0
  9. data/lib/vanilla/app.rb +87 -0
  10. data/lib/vanilla/console.rb +3 -0
  11. data/lib/vanilla/dynasnip.rb +110 -0
  12. data/lib/vanilla/dynasnips/code.rb +16 -0
  13. data/lib/vanilla/dynasnips/comments.rb +108 -0
  14. data/lib/vanilla/dynasnips/current_snip.rb +32 -0
  15. data/lib/vanilla/dynasnips/debug.rb +13 -0
  16. data/lib/vanilla/dynasnips/edit.rb +63 -0
  17. data/lib/vanilla/dynasnips/edit_link.rb +24 -0
  18. data/lib/vanilla/dynasnips/index.rb +11 -0
  19. data/lib/vanilla/dynasnips/kind.rb +70 -0
  20. data/lib/vanilla/dynasnips/link_to.rb +14 -0
  21. data/lib/vanilla/dynasnips/link_to_current_snip.rb +16 -0
  22. data/lib/vanilla/dynasnips/login.rb +56 -0
  23. data/lib/vanilla/dynasnips/new.rb +14 -0
  24. data/lib/vanilla/dynasnips/notes.rb +42 -0
  25. data/lib/vanilla/dynasnips/pre.rb +19 -0
  26. data/lib/vanilla/dynasnips/rand.rb +27 -0
  27. data/lib/vanilla/dynasnips/raw.rb +19 -0
  28. data/lib/vanilla/dynasnips/url_to.rb +7 -0
  29. data/lib/vanilla/renderers/base.rb +78 -0
  30. data/lib/vanilla/renderers/bold.rb +9 -0
  31. data/lib/vanilla/renderers/erb.rb +16 -0
  32. data/lib/vanilla/renderers/markdown.rb +13 -0
  33. data/lib/vanilla/renderers/raw.rb +9 -0
  34. data/lib/vanilla/renderers/ruby.rb +35 -0
  35. data/lib/vanilla/renderers/textile.rb +13 -0
  36. data/lib/vanilla/request.rb +68 -0
  37. data/lib/vanilla/routes.rb +29 -0
  38. data/lib/vanilla/snip_handling.rb +33 -0
  39. data/lib/vanilla/snips/start.rb +18 -0
  40. data/lib/vanilla/snips/system.rb +76 -0
  41. data/lib/vanilla/snips/tutorial.rb +158 -0
  42. data/lib/vanilla/test_snips.rb +85 -0
  43. data/spec/dynasnip_spec.rb +31 -0
  44. data/spec/renderers/base_renderer_spec.rb +40 -0
  45. data/spec/renderers/erb_renderer_spec.rb +27 -0
  46. data/spec/renderers/markdown_renderer_spec.rb +29 -0
  47. data/spec/renderers/raw_renderer_spec.rb +21 -0
  48. data/spec/renderers/ruby_renderer_spec.rb +42 -0
  49. data/spec/renderers/vanilla_app_detecting_renderer_spec.rb +35 -0
  50. data/spec/soup_test.db +0 -0
  51. data/spec/spec_helper.rb +64 -0
  52. data/spec/vanilla_app_spec.rb +38 -0
  53. data/spec/vanilla_presenting_spec.rb +84 -0
  54. data/spec/vanilla_request_spec.rb +73 -0
  55. data/spec/vanilla_snip_finding_spec.rb +28 -0
  56. metadata +173 -0
data/README ADDED
@@ -0,0 +1,53 @@
1
+ --~::{ Vanilla.rb }::~---
2
+ =========================
3
+
4
+ A wandering soul; a repo clone'd -
5
+ his meta_klass and methods honed.
6
+ But tarry he 'ponst what dark endeavour
7
+ with code of such unknowable terror?
8
+
9
+ - H.P. Gemcraft, 1914
10
+
11
+ A Preface; A Warning
12
+ ====================
13
+
14
+ The base flavour. The classic ice cream. Except riddled through with blood-red gemstones - Ruby gemstones.
15
+ This mad gelato will break your teeth.
16
+
17
+ ... and run the freakiest wiki-wonki-wiki-wonki-wiki-wonki-wickedy-wiki you've ever seen.
18
+
19
+ But you must not fear: fear is the mind-killer; fear is the little death that brings total oblivion;
20
+ fear is the chilling terror that makes you believe that *everything* is better when Model lays with
21
+ Controller and View in peace.
22
+
23
+ Vanilla.rb cries "HERESY!" upon that layered orgy of filth. Vanilla.rb says "EMBRACE CHAOS!". Vanilla.rb
24
+ says "EVERY SNIP FOR THEMSELVES!". Vanilla.rb waits quietly, in the dark corners.
25
+
26
+ Use at your own risk; really. I showed it to a cat, and the cat started talking in French.
27
+ It was MESSED. UP.
28
+
29
+
30
+ Thee Darke Invocation
31
+ =====================
32
+
33
+ $ gem install vanilla
34
+
35
+ $ vanilla my_app_name
36
+
37
+ ... a bunch of stuff gets created
38
+
39
+ $ cd my_app_name
40
+ $ rackup
41
+
42
+ ... the wonki starts. THE PAIN BEGINS.
43
+
44
+ (Try going to http://localhost:9292/vanilla-rb-tutorial to salve the chafing.)
45
+
46
+
47
+ Working with Vanilla
48
+ ====================
49
+
50
+ Currently unknowable; soon I hope to compile such a nercronomicon as to allow mortal kind to
51
+ conjure up Snips and Dynasnips and Renderers...
52
+
53
+ For the moment, see http://interblah.net/vanilla-rb-tutorial
data/Rakefile ADDED
@@ -0,0 +1,121 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
2
+ require 'vanilla'
3
+
4
+ require 'spec'
5
+ require 'spec/rake/spectask'
6
+ Spec::Rake::SpecTask.new do |t|
7
+ t.spec_opts = %w(--format specdoc --colour)
8
+ t.libs = ["spec"]
9
+ end
10
+
11
+ task :default => :spec
12
+
13
+
14
+ require "rubygems"
15
+ require "rake/gempackagetask"
16
+ require "rake/rdoctask"
17
+
18
+ # This builds the actual gem. For details of what all these options
19
+ # mean, and other ones you can add, check the documentation here:
20
+ #
21
+ # http://rubygems.org/read/chapter/20
22
+ #
23
+ spec = Gem::Specification.new do |s|
24
+
25
+ # Change these as appropriate
26
+ s.name = "vanilla"
27
+ s.version = "1.0.1"
28
+ s.summary = "A bliki-type web content thing."
29
+ s.author = "James Adam"
30
+ s.email = "james@lazyatom.com.com"
31
+ s.homepage = "http://github.com/lazyatom/vanilla-rb"
32
+
33
+ s.has_rdoc = true
34
+ s.extra_rdoc_files = %w(README)
35
+ s.rdoc_options = %w(--main README)
36
+
37
+ # Add any extra files to include in the gem
38
+ s.files = %w(config.example.yml config.ru Rakefile README) + Dir.glob("{spec,lib,bin}/**/*")
39
+ s.executables = ['vanilla']
40
+ s.require_paths = ["lib"]
41
+
42
+ # All the other gems we need.
43
+ s.add_dependency("rack", ">= 0.9.1")
44
+ s.add_dependency("soup", ">= 0.2.1")
45
+ s.add_dependency("ratom", ">= 0.3.5")
46
+ s.add_dependency("RedCloth", ">= 4.1.1")
47
+ s.add_dependency("BlueCloth", ">= 1.0.0")
48
+
49
+ s.add_development_dependency("rspec") # add any other gems for testing/development
50
+
51
+ # If you want to publish automatically to rubyforge, you'll may need
52
+ # to tweak this, and the publishing task below too.
53
+ s.rubyforge_project = "vanilla"
54
+ end
55
+
56
+ # This task actually builds the gem. We also regenerate a static
57
+ # .gemspec file, which is useful if something (i.e. GitHub) will
58
+ # be automatically building a gem for this project. If you're not
59
+ # using GitHub, edit as appropriate.
60
+ Rake::GemPackageTask.new(spec) do |pkg|
61
+ pkg.gem_spec = spec
62
+
63
+ # Generate the gemspec file for github.
64
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
65
+ File.open(file, "w") {|f| f << spec.to_ruby }
66
+ end
67
+
68
+ # Generate documentation
69
+ Rake::RDocTask.new do |rd|
70
+ rd.main = "README"
71
+ rd.rdoc_files.include("README", "lib/**/*.rb")
72
+ rd.rdoc_dir = "rdoc"
73
+ end
74
+
75
+ desc 'Clear out RDoc and generated packages'
76
+ task :clean => [:clobber_rdoc, :clobber_package] do
77
+ rm "#{spec.name}.gemspec"
78
+ end
79
+
80
+ # If you want to publish to RubyForge automatically, here's a simple
81
+ # task to help do that. If you don't, just get rid of this.
82
+ # Be sure to set up your Rubyforge account details with the Rubyforge
83
+ # gem; you'll need to run `rubyforge setup` and `rubyforge config` at
84
+ # the very least.
85
+ begin
86
+ require "rake/contrib/sshpublisher"
87
+ namespace :rubyforge do
88
+
89
+ desc "Release gem and RDoc documentation to RubyForge"
90
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
91
+
92
+ namespace :release do
93
+ desc "Release a new version of this gem"
94
+ task :gem => [:package] do
95
+ require 'rubyforge'
96
+ rubyforge = RubyForge.new
97
+ rubyforge.configure
98
+ rubyforge.login
99
+ rubyforge.userconfig['release_notes'] = spec.summary
100
+ path_to_gem = File.join(File.dirname(__FILE__), "pkg", "#{spec.name}-#{spec.version}.gem")
101
+ puts "Publishing #{spec.name}-#{spec.version.to_s} to Rubyforge..."
102
+ rubyforge.add_release(spec.rubyforge_project, spec.name, spec.version.to_s, path_to_gem)
103
+ end
104
+
105
+ desc "Publish RDoc to RubyForge."
106
+ task :docs => [:rdoc] do
107
+ config = YAML.load(
108
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
109
+ )
110
+
111
+ host = "#{config['username']}@rubyforge.org"
112
+ remote_dir = "/var/www/gforge-projects/vanilla-rb/" # Should be the same as the rubyforge project name
113
+ local_dir = 'rdoc'
114
+
115
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
116
+ end
117
+ end
118
+ end
119
+ rescue LoadError
120
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
121
+ end
data/bin/vanilla ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'rake'
4
+ load File.join(File.dirname(__FILE__), *%w[.. lib tasks vanilla.rake])
5
+
6
+ mkdir(ARGV[0])
7
+ cd(ARGV[0])
8
+
9
+ Rake::Task['vanilla:setup'].invoke
@@ -0,0 +1,5 @@
1
+ ---
2
+ :filename: config.example.yml
3
+ :secret: a6bc097eff86cabd92ee72ba4687c3f057b7556deaa3e4a6b284460871056b87ba3e91548c37dcc44fbc10241cee5b386556e6bcc2946fd9b609dc3bc1b24488
4
+ :credentials:
5
+ admin: 5f4dcc3b5aa765d61d8327deb882cf99
data/config.ru ADDED
@@ -0,0 +1,9 @@
1
+ require 'vanilla'
2
+
3
+ app = Vanilla::App.new(ENV['VANILLA_CONFIG'])
4
+ use Rack::Session::Cookie, :key => 'vanilla.session',
5
+ :path => '/',
6
+ :expire_after => 2592000,
7
+ :secret => app.config[:secret]
8
+ use Rack::Static, :urls => ["/public"], :root => File.join(File.dirname(__FILE__))
9
+ run app
data/lib/defensio.rb ADDED
@@ -0,0 +1,59 @@
1
+ class Defensio
2
+ class << self
3
+ attr_accessor :format
4
+ attr_accessor :service_type
5
+ attr_accessor :api_version
6
+ attr_accessor :api_key
7
+ attr_accessor :owner_url
8
+ end
9
+
10
+ self.format = :xml
11
+ self.service_type = :app # Can be :blog
12
+ self.api_version = '1.2'
13
+
14
+ def self.configure(confhash)
15
+ if confhash['test']
16
+ @mock = true
17
+ self.owner_url = 'http://www.example.com'
18
+ return
19
+ else
20
+ confhash.each do |prop, val|
21
+ self.send("#{prop}=", val)
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.method_missing(name, *args)
27
+ self.post(name.to_s.dasherize, *args)
28
+ end
29
+
30
+ private
31
+ def self.connection
32
+ uri = URI.parse('http://api.defensio.com/')
33
+ Net::HTTP.start(uri.host, uri.port)
34
+ end
35
+
36
+ def self.post(action, params = {})
37
+ resp = connection.post(real_path(action), params_from_hash(params))
38
+ raise "Problem with request: #{action}" unless resp.code == '200'
39
+ parse_response(resp.body)
40
+ end
41
+
42
+ def self.real_path(action)
43
+ "/#{service_type}/#{api_version}/#{action}/#{api_key}.#{format}"
44
+ end
45
+
46
+ def self.params_from_hash(params = {})
47
+ # Thanks Net::HTTPHeader
48
+ params.stringify_keys.merge('owner-url' => owner_url).map {|k,v| "#{CGI.escape(k.dasherize.to_s)}=#{CGI.escape(v.to_s)}" }.join('&')
49
+ end
50
+
51
+ def self.parse_response(body)
52
+ case format
53
+ when :yaml
54
+ YAML.load(body)
55
+ when :xml
56
+ Hash.from_xml(body)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,178 @@
1
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..')))
2
+ require 'vanilla'
3
+
4
+ namespace :vanilla do
5
+ desc "Open an irb session preloaded with this library"
6
+ task :console do
7
+ sh "irb -Ilib -rubygems -rvanilla -rvanilla/console"
8
+ end
9
+
10
+ task :clean do
11
+ # TODO: get the database name from Soup
12
+ FileUtils.rm "soup.db" if File.exist?("soup.db")
13
+ end
14
+
15
+ task :prepare do
16
+ Soup.prepare
17
+ end
18
+
19
+ task :load_snips => :prepare do
20
+ Dynasnip.persist_all!(overwrite=true)
21
+
22
+ Dir[File.join(File.dirname(__FILE__), '..', 'vanilla', 'snips', '*.rb')].each do |f|
23
+ p "loading #{f}"
24
+ load f
25
+ end
26
+
27
+ load File.join(File.dirname(__FILE__), *%w[.. vanilla test_snips.rb])
28
+
29
+ puts "The soup is simmering. Loaded #{Soup.tuple_class.count} tuples"
30
+ end
31
+
32
+ desc 'Resets the soup to contain the base snips only. Dangerous!'
33
+ task :reset => [:clean, :load_snips]
34
+
35
+ namespace :upgrade do
36
+ desc 'Upgrade the dynasnips'
37
+ task :dynasnips => :prepare do
38
+ Dynasnip.all.each do |dynasnip|
39
+ print "Upgrading #{dynasnip.snip_name}... "
40
+ # TODO: our confused Soup interface might return an array.
41
+ snip = Soup[dynasnip.snip_name]
42
+ if snip.empty? || snip.nil?
43
+ # it's a new dyna
44
+ Soup << dynasnip.snip_attributes
45
+ puts "(new)"
46
+ elsif snip.created_at == snip.updated_at
47
+ # it's not been changed, let's upgrade
48
+ snip.destroy
49
+ Soup << dynasnip.snip_attributes
50
+ puts "(unedited)"
51
+ else
52
+ # the dyna exists and has been changed
53
+ dynasnip.snip_attributes.each do |name, value|
54
+ unless (existing_value = snip.get_value(name)) == value
55
+ puts "Conflict in attribute '#{name}':"
56
+ puts "> Your soup: '#{existing_value}'"
57
+ puts "> New soup: '#{value}"
58
+ print "Upgrade? [Y/n]: "
59
+ upgrade_value = ["Y", "y", ""].include? STDIN.gets.chomp.strip
60
+ snip.set_value(name, value) if upgrade_value
61
+ end
62
+ end
63
+ snip.save
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ desc 'Upgrade dynasnips and system snips'
70
+ task :upgrade => ["upgrade:dynasnips"]
71
+
72
+ desc 'Add a user (or change an existing password)'
73
+ task :add_user => :prepare do
74
+ puts "Adding a new user"
75
+ # config_file = ENV['VANILLA_CONFIG'] || 'config.yml'
76
+ # config_file = YAML.load(File.open(config_file)) rescue {}
77
+ app = Vanilla::App.new(ENV['VANILLA_CONFIG'])
78
+ print "Username: "
79
+ username = STDIN.gets.chomp.strip
80
+ print "Password: "
81
+ password = STDIN.gets.chomp.strip
82
+ print "Confirm password: "
83
+ confirm_password = STDIN.gets.chomp.strip
84
+ if password != confirm_password
85
+ raise "Passwords don't match!"
86
+ else
87
+ app.config[:credentials] ||= {}
88
+ app.config[:credentials][username] = MD5.md5(password).to_s
89
+ app.config.save!
90
+ puts "User '#{username}' added."
91
+ end
92
+ end
93
+
94
+ desc 'Generate file containing secret for cookie-based session storage'
95
+ task :generate_secret do
96
+ # Adapted from old rails secret generator.
97
+ require 'openssl'
98
+ if !File.exist?("/dev/urandom")
99
+ # OpenSSL transparently seeds the random number generator with
100
+ # data from /dev/urandom. On platforms where that is not
101
+ # available, such as Windows, we have to provide OpenSSL with
102
+ # our own seed. Unfortunately there's no way to provide a
103
+ # secure seed without OS support, so we'll have to do with
104
+ # rand() and Time.now.usec().
105
+ OpenSSL::Random.seed(rand(0).to_s + Time.now.usec.to_s)
106
+ end
107
+ data = OpenSSL::BN.rand(2048, -1, false).to_s
108
+ secret = OpenSSL::Digest::SHA512.new(data).hexdigest
109
+ app = Vanilla::App.new(ENV['VANILLA_CONFIG'])
110
+ app.config[:secret] = secret
111
+ app.config.save!
112
+ puts "Secret generated."
113
+ end
114
+
115
+ desc 'Prepare standard files to run Vanilla'
116
+ task :prepare_files do
117
+ cp File.join(File.dirname(__FILE__), *%w[.. .. config.ru]), 'config.ru'
118
+ cp_r File.join(File.dirname(__FILE__), *%w[.. .. public]), 'public'
119
+ mkdir 'tmp'
120
+ File.open("Rakefile", "w") do |f|
121
+ rakefile =<<-EOF
122
+ require 'vanilla'
123
+ load 'tasks/vanilla.rake'
124
+
125
+ # Add any other tasks here.
126
+ EOF
127
+ f.write rakefile.strip
128
+ end
129
+ end
130
+
131
+
132
+ desc 'Prepare a new vanilla.rb installation'
133
+ task :setup do
134
+ puts <<-EOM
135
+
136
+ ===================~ Vanilla.rb ~====================
137
+
138
+ Congratulations! You have elected to try out the weirdest web thing ever.
139
+ Lets get started. Firstly, I'm going to cook you some soup:
140
+
141
+
142
+ EOM
143
+ Rake::Task['vanilla:load_snips'].invoke
144
+
145
+ puts <<-EOM
146
+
147
+ Now I'm going to generate your configuration. This will be stored either in
148
+ 'config.yml' in the current directory, or in the path you provide via the
149
+ environment variable VANILLA_CONFIG.
150
+
151
+ Generating the secret for cookie-based session storage.
152
+ EOM
153
+ Rake::Task['vanilla:prepare_files'].invoke
154
+ Rake::Task['vanilla:generate_secret'].invoke
155
+
156
+ puts <<-EOM
157
+
158
+
159
+ Now that we've got our broth, you'll want to add a user, so you can edit stuff.
160
+ Lets do that now:
161
+
162
+
163
+ EOM
164
+ Rake::Task['vanilla:add_user'].invoke
165
+ puts <<-EOM
166
+
167
+
168
+ OK! You're ready to go. To start vanilla.rb, you'll want to get it running under
169
+ a webserver that supports Rack. The easiest way to do this locally is via 'rackup':
170
+
171
+ $ rackup
172
+
173
+ Then go to http://localhost:9292
174
+
175
+ I'm going now, Goodbye!
176
+ EOM
177
+ end
178
+ end
data/lib/vanilla.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+
3
+ gem 'soup', '>= 0.1.4'
4
+ require 'soup'
5
+ require 'vanilla/snip_handling'
6
+
7
+ module Vanilla
8
+ include SnipHandling
9
+ end
10
+
11
+ # Load all the other renderer subclasses
12
+ Dir[File.join(File.dirname(__FILE__), 'vanilla', 'renderers', '*.rb')].each { |f| require f }
13
+
14
+ # Load the routing information
15
+ require 'vanilla/routes'
16
+
17
+ # Load all the base dynasnip classes
18
+ Dir[File.join(File.dirname(__FILE__), 'vanilla', 'dynasnips', '*.rb')].each do |dynasnip|
19
+ require dynasnip
20
+ end