dayvan 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/{dayvan → dvn} +1 -1
- data/lib/dayvan/attachment.rb +54 -0
- data/lib/dayvan/cli.rb +57 -0
- data/lib/dayvan/design.rb +77 -0
- data/lib/dayvan/project.rb +55 -0
- data/lib/dayvan/security.rb +30 -0
- data/lib/dayvan/view.rb +49 -0
- data/lib/dayvan.rb +19 -0
- data/templates/all.coffee.erb +2 -0
- data/templates/security.coffee.erb +2 -0
- data/templates/size.coffee.erb +5 -0
- data/templates/welcome.html.erb +27 -0
- metadata +16 -4
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ begin
|
|
7
7
|
gem.email = 'christopher.lloyd@gmail.com'
|
8
8
|
gem.homepage = 'http://github.com/chrislloyd/dayvan'
|
9
9
|
gem.author = 'Chris Lloyd'
|
10
|
-
gem.executable = '
|
10
|
+
gem.executable = 'dvn'
|
11
11
|
|
12
12
|
gem.add_dependency 'thor', '>= 0.12.3'
|
13
13
|
gem.add_dependency 'rest-client', '>= 1.2.0'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/bin/{dayvan → dvn}
RENAMED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'digest/md5'
|
3
|
+
require 'mime/types'
|
4
|
+
|
5
|
+
class Dayvan::Attachment
|
6
|
+
|
7
|
+
def self.all(root)
|
8
|
+
Dir[root.join('**/**')].
|
9
|
+
reject {|f| File.directory?(f)}. # Allows symlinks
|
10
|
+
inject({}) {|all, f|
|
11
|
+
attachment = new(f)
|
12
|
+
all[attachment.path.relative_path_from(root)] = attachment
|
13
|
+
all
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.signatures
|
18
|
+
all.inject({}) do |signatures, (path, attachment)|
|
19
|
+
signatures[path] = attachment.signature
|
20
|
+
signatures
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :path
|
25
|
+
|
26
|
+
def initialize(path)
|
27
|
+
self.path = path
|
28
|
+
end
|
29
|
+
|
30
|
+
def content_type
|
31
|
+
(MIME::Types.of(path.to_s).first || 'text/plain').to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
def data
|
35
|
+
Base64.encode64(path.read).delete("\s\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
def name
|
39
|
+
path.basename('*.*')
|
40
|
+
end
|
41
|
+
|
42
|
+
def path=(path)
|
43
|
+
@path = Pathname(path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def signature
|
47
|
+
Digest::MD5.hexdigest(data)
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_json
|
51
|
+
{:content_type => content_type, :data => data}.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/lib/dayvan/cli.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'thor'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Dayvan::Cli < Thor
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
source_paths << Pathname(__FILE__).dirname.join('..','..','templates').expand_path.to_s
|
9
|
+
|
10
|
+
desc 'init', 'Create a CouchApp template'
|
11
|
+
def init
|
12
|
+
destination_root = Pathname.pwd
|
13
|
+
source_path = Pathname(__FILE__).dirname.expand_path
|
14
|
+
name = destination_root.basename.to_s
|
15
|
+
|
16
|
+
|
17
|
+
empty_directory 'config'
|
18
|
+
|
19
|
+
create_file "config/#{name}.yaml" do
|
20
|
+
{'designs' => [name.to_s],
|
21
|
+
'database' => {
|
22
|
+
'url' => "http://localhost:5984/#{name}"
|
23
|
+
}
|
24
|
+
}.to_yaml.split("\n")[1..-1].join("\n") + "\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
copy_file 'security.coffee.erb', 'config/security.coffee'
|
28
|
+
|
29
|
+
empty_directory 'views'
|
30
|
+
copy_file 'all.coffee.erb', 'views/all.coffee'
|
31
|
+
copy_file 'size.coffee.erb', 'views/size.coffee'
|
32
|
+
|
33
|
+
empty_directory 'public'
|
34
|
+
@name = name
|
35
|
+
@version = Dayvan.version
|
36
|
+
template 'welcome.html.erb', 'public/index.html'
|
37
|
+
|
38
|
+
puts "Initialized CouchApp in #{destination_root}"
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'push', 'Push your app to CouchDB'
|
42
|
+
def push
|
43
|
+
Dayvan.project.create_database!
|
44
|
+
Dayvan.project.push!
|
45
|
+
rescue Errno::ECONNREFUSED, RestClient::Unauthorized
|
46
|
+
abort "fatal: Couldn't connect to CouchDB at #{Dayvan.project.db.url}"
|
47
|
+
rescue Dayvan::ConfigError
|
48
|
+
abort "fatal: Not a Dayvan app"
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def project
|
54
|
+
Dayvan.project
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class Dayvan::Design
|
2
|
+
|
3
|
+
attr_accessor :name, :config
|
4
|
+
attr_writer :rev
|
5
|
+
|
6
|
+
def self.new_from_config(name, config={})
|
7
|
+
returning(new) do |d|
|
8
|
+
if name.is_a?(Hash)
|
9
|
+
d.name = name.delete('name')
|
10
|
+
d.config = name
|
11
|
+
else
|
12
|
+
d.name = name
|
13
|
+
d.config = config
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def doc
|
19
|
+
Dayvan.project.db[id]
|
20
|
+
end
|
21
|
+
|
22
|
+
def id
|
23
|
+
"_design/#{name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def rev
|
27
|
+
@rev ||= JSON.parse(doc.get)['_rev']
|
28
|
+
rescue RestClient::ResourceNotFound
|
29
|
+
end
|
30
|
+
|
31
|
+
def attachments
|
32
|
+
Dayvan::Attachment.all(attachment_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def attachment_path
|
36
|
+
config['attachments'] ||
|
37
|
+
config['attachment'] ||
|
38
|
+
Dayvan.project.dir.join('public')
|
39
|
+
end
|
40
|
+
|
41
|
+
def views
|
42
|
+
Dayvan::View.all(view_path)
|
43
|
+
end
|
44
|
+
|
45
|
+
def view_path
|
46
|
+
config['views'] ||
|
47
|
+
config['view'] ||
|
48
|
+
Dayvan.project.dir.join('views')
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate_doc_update
|
52
|
+
Dayvan::Security.new(validate_doc_update_path)
|
53
|
+
end
|
54
|
+
|
55
|
+
def validate_doc_update_path
|
56
|
+
config['security'] ||
|
57
|
+
Dayvan.project.dir.join('config','security.coffee')
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def to_hash
|
62
|
+
hsh = { '_attachments' => attachments,
|
63
|
+
'views' => views,
|
64
|
+
'validate_doc_update' => validate_doc_update
|
65
|
+
}
|
66
|
+
rev ? hsh.merge('_rev' => rev) : hsh
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_json
|
70
|
+
to_hash.to_json
|
71
|
+
end
|
72
|
+
|
73
|
+
def push
|
74
|
+
doc.put to_json
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yaml'
|
3
|
+
require 'restclient'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
class Dayvan::ConfigError < StandardError; end
|
7
|
+
|
8
|
+
class Dayvan::Project
|
9
|
+
|
10
|
+
def dir
|
11
|
+
Pathname.pwd
|
12
|
+
end
|
13
|
+
|
14
|
+
def designs
|
15
|
+
config['designs'].
|
16
|
+
map {|design| Dayvan::Design.new_from_config(design)}
|
17
|
+
end
|
18
|
+
|
19
|
+
def config
|
20
|
+
@config ||= YAML.load(config_path.read)
|
21
|
+
end
|
22
|
+
|
23
|
+
def db
|
24
|
+
url, dbname = config['database']['url'], config['database']['name']
|
25
|
+
user, password = config['database']['user'], config['database']['password']
|
26
|
+
@db ||= RestClient::Resource.new(url,
|
27
|
+
:user => user,
|
28
|
+
:password => password
|
29
|
+
)[dbname]
|
30
|
+
end
|
31
|
+
|
32
|
+
def config_path
|
33
|
+
dirname = dir.expand_path.basename
|
34
|
+
["#{dirname}.yaml", "#{dirname}.yml", 'divan.yaml', 'divan.yml'].
|
35
|
+
inject([]) {|dirs, f|
|
36
|
+
dirs << dir.join('config',f)
|
37
|
+
dirs << dir.join(f)
|
38
|
+
dirs
|
39
|
+
}.
|
40
|
+
find {|dir| dir.file? && dir.readable?} ||
|
41
|
+
raise(Dayvan::ConfigError)
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_database!
|
45
|
+
db.put nil
|
46
|
+
rescue RestClient::RequestFailed
|
47
|
+
end
|
48
|
+
|
49
|
+
def push!
|
50
|
+
designs.each do |d|
|
51
|
+
d.push
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'coffee-script'
|
2
|
+
|
3
|
+
class Dayvan::Security
|
4
|
+
|
5
|
+
def self.all
|
6
|
+
new(Dayvan.project.security_path)
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :path
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
self.path = path
|
13
|
+
end
|
14
|
+
|
15
|
+
def src
|
16
|
+
path.read
|
17
|
+
end
|
18
|
+
|
19
|
+
def compile
|
20
|
+
CoffeeScript::Parser.new.parse(src).
|
21
|
+
children.
|
22
|
+
find {|node| node.is_a?(CoffeeScript::CodeNode)}.
|
23
|
+
compile(:indent => '')
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_json
|
27
|
+
compile.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/dayvan/view.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'coffee-script'
|
2
|
+
|
3
|
+
class Dayvan::View
|
4
|
+
attr_accessor :path
|
5
|
+
|
6
|
+
def self.all(root)
|
7
|
+
Dir[root.join('**/*.coffee')].
|
8
|
+
reject {|f| File.directory?(f)}. # Allows symlinks
|
9
|
+
inject({}) {|all, f|
|
10
|
+
view = new(f)
|
11
|
+
all[view.name] = view
|
12
|
+
all
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def initialize(path)
|
18
|
+
self.path = path
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
File.basename(path, '.*')
|
23
|
+
end
|
24
|
+
|
25
|
+
def src
|
26
|
+
File.read(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def compile
|
30
|
+
parse_tree = CoffeeScript::Parser.new.parse(src)
|
31
|
+
|
32
|
+
['map', 'reduce'].inject({}) do |memo, type|
|
33
|
+
# Finds tops level assignemnts whose bound variable is map/reduce.
|
34
|
+
assignment_node = parse_tree.children.find {|node|
|
35
|
+
node.is_a?(CoffeeScript::AssignNode) && node.variable.base == type
|
36
|
+
}
|
37
|
+
|
38
|
+
if assignment_node
|
39
|
+
memo[type] = assignment_node.value.compile(:indent => '')
|
40
|
+
end
|
41
|
+
memo
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_json
|
46
|
+
compile.to_json
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/dayvan.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
def returning(val)
|
4
|
+
yield val
|
5
|
+
val
|
6
|
+
end unless respond_to?(:returning)
|
7
|
+
|
8
|
+
module Dayvan
|
9
|
+
def self.version
|
10
|
+
Pathname(__FILE__).dirname.join('..','VERSION').read.strip.freeze
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.project
|
14
|
+
@project ||= Dayvan::Project.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
%w(attachment view security design project cli).
|
19
|
+
each {|lib| require "dayvan/#{lib}"}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<meta charset=utf-8>
|
3
|
+
<title>Welcome to Dayvan</title>
|
4
|
+
<style type=text/css>
|
5
|
+
body { font-family: Junction, Helvetica; margin: 40px auto; width: 360px; line-height: 20px; font-size: 14px; color: #666; }
|
6
|
+
#video { border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; overflow: hidden; line-height: 0; display: block; margin: 0 -20px; }
|
7
|
+
#video, object, embed { background-color: #336; }
|
8
|
+
hgroup { display: block; clear: both; overflow: auto; margin-top: 10px; }
|
9
|
+
hgroup h1 { font-size: 18px; font-weight: normal; color: #336; float: left; }
|
10
|
+
hgroup h2 { float: right; color: #999; font-size: 14px; margin-top: 13px; font-weight: normal; }
|
11
|
+
code { font-family: Inconsolata, monospace; font-size: 16px; color: #333; }
|
12
|
+
.footer { font-size: 12px; margin-top: 20px; }
|
13
|
+
a { color: #69C; text-decoration: none; }
|
14
|
+
a:hover { color: #06C; }
|
15
|
+
</style>
|
16
|
+
|
17
|
+
<div id=video>
|
18
|
+
<object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=5125966&server=vimeo.com&show_title=0&show_byline=0&show_portrait=0&color=ffffff&fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=5125966&server=vimeo.com&show_title=0&show_byline=0&show_portrait=0&color=ffffff&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<hgroup>
|
22
|
+
<h1>Thank you for using <b>Dayvan</b></h1>
|
23
|
+
<h2>v<%= @version %></h2>
|
24
|
+
</hgroup>
|
25
|
+
<p>Push new versions of your app again with <code>dvn push</code>.</p>
|
26
|
+
<p>Add attachments to <code>public</code> directory and views to the <code>views</code> directory. These settings can be changed in the <code>config/<%= @name %>.yaml</code> file.</p>
|
27
|
+
<p class=footer><a href=http://chrislloyd.github.com/dayvan>Reference</a> · <a href=http://github.com/chrislloyd/dayvan>Code</a> · <a href=http://thelincolnshirepoacher.com>The Poacher</a></p>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dayvan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Lloyd
|
@@ -9,8 +9,8 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
13
|
-
default_executable:
|
12
|
+
date: 2010-02-03 00:00:00 +11:00
|
13
|
+
default_executable: dvn
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: thor
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
description: Dayvan is a framework for writing CouchApps.
|
66
66
|
email: christopher.lloyd@gmail.com
|
67
67
|
executables:
|
68
|
-
-
|
68
|
+
- dvn
|
69
69
|
extensions: []
|
70
70
|
|
71
71
|
extra_rdoc_files:
|
@@ -75,6 +75,18 @@ files:
|
|
75
75
|
- README.rdoc
|
76
76
|
- Rakefile
|
77
77
|
- VERSION
|
78
|
+
- bin/dvn
|
79
|
+
- lib/dayvan.rb
|
80
|
+
- lib/dayvan/attachment.rb
|
81
|
+
- lib/dayvan/cli.rb
|
82
|
+
- lib/dayvan/design.rb
|
83
|
+
- lib/dayvan/project.rb
|
84
|
+
- lib/dayvan/security.rb
|
85
|
+
- lib/dayvan/view.rb
|
86
|
+
- templates/all.coffee.erb
|
87
|
+
- templates/security.coffee.erb
|
88
|
+
- templates/size.coffee.erb
|
89
|
+
- templates/welcome.html.erb
|
78
90
|
has_rdoc: true
|
79
91
|
homepage: http://github.com/chrislloyd/dayvan
|
80
92
|
licenses: []
|