dayvan 0.0.0 → 0.1.0
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/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: []
|