zdzolton-cambric 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -104,14 +104,37 @@ by the application.
104
104
 
105
105
  * Install gems:
106
106
 
107
- $ sudo gem install jchris-couchapp jchris-couchrest zdzolton-cambric
107
+ $ sudo gem install jchris-couchrest zdzolton-cambric
108
108
 
109
109
  * Configure Rails:
110
110
  * create a config/initializers/cambric.rb file as follows:
111
111
 
112
- # coming soon...
112
+ Cambric.configure do |config|
113
+ config.design_doc_name = 'YOUR_APP_NAME'
114
+ config.environment = RAILS_ENV
115
+
116
+ config.databases = {
117
+ :YOUR_DB_NAME => {
118
+ :development => "http://localhost:5984/YOUR_DB_NAME-development",
119
+ :test => "http://localhost:5984/YOUR_DB_NAME-test"
120
+ },
121
+ :YOUR_OTHER_DB => {
122
+ :development => "http://localhost:5984/YOUR_OTHER_DB-development",
123
+ :test => "http://localhost:5984/YOUR_OTHER_DB-test"
124
+ }
125
+ }
126
+ end
127
+
128
+ # Push design docs after every request in development, and once in production on app startup
129
+ ActionController::Dispatcher.to_prepare(:cambric){ Cambric.prepare_databases }
130
+
131
+ * place the following two lines in your test_helper.rb, at the top of the file after the
132
+ require statements:
133
+
134
+ Cambric.environment = 'test'
135
+ Cambric.prepare_databases!
113
136
 
114
- * create a couchdb directory within your project
137
+ * create a couchdb directory within your project:
115
138
 
116
139
  $ cd /your/app/root
117
140
  $ mkdir -p ./couchdb/your_db/views/some_view_name
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.3
1
+ 0.6.4
data/cambric.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{cambric}
5
- s.version = "0.6.3"
5
+ s.version = "0.6.4"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Zachary Zolton", "Geoff Buesing"]
9
- s.date = %q{2009-06-09}
9
+ s.date = %q{2009-07-08}
10
10
  s.email = %q{zachary.zolton@gmail.com}
11
11
  s.extra_rdoc_files = [
12
12
  "LICENSE",
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  "lib/cambric.rb",
24
24
  "lib/cambric/assume_design_doc_name.rb",
25
25
  "lib/cambric/configurator.rb",
26
+ "lib/cambric/file_manager.rb",
26
27
  "lib/cambric/test_helpers.rb",
27
28
  "spec/cambric/assume_design_doc_name_spec.rb",
28
29
  "spec/cambric/cambric_spec.rb",
@@ -4,12 +4,8 @@ module Cambric
4
4
  attr_accessor :cambric_design_doc_name
5
5
 
6
6
  def view name, options={}, &block
7
- case name
8
- when String
9
- super name, options, &block
10
- when Symbol
11
- super "#{@cambric_design_doc_name}/#{name}", options, &block
12
- end
7
+ name = "#{@cambric_design_doc_name}/#{name}" if name.is_a?(Symbol)
8
+ super name, options, &block
13
9
  end
14
10
 
15
11
  def cambric_design_doc
@@ -0,0 +1,234 @@
1
+ module Cambric
2
+
3
+ # This class has been ripped off from jchris-couchapp... Thanks, jchris!
4
+ class FileManager
5
+ attr_reader :db
6
+ attr_accessor :loud
7
+
8
+ LANGS = {"rb" => "ruby", "js" => "javascript"}
9
+ MIMES = {
10
+ "html" => "text/html",
11
+ "htm" => "text/html",
12
+ "png" => "image/png",
13
+ "gif" => "image/gif",
14
+ "css" => "text/css",
15
+ "js" => "test/javascript",
16
+ "txt" => "text/plain"
17
+ }
18
+
19
+ # # Generate an application in the given directory.
20
+ # # This is a class method because it doesn't depend on
21
+ # # specifying a database.
22
+ # def self.generate_app(app_dir, loud = false)
23
+ # templatedir = File.join(File.expand_path(File.dirname(__FILE__)),
24
+ # '..', '..', 'app-template')
25
+ # FileUtils.cp_r(templatedir, app_dir)
26
+ # puts Dir[app_dir+'/**/*'] if loud
27
+ # end
28
+
29
+ # instance methods
30
+
31
+ def initialize(dbname, host="http://127.0.0.1:5984")
32
+ @db = CouchRest.new(host).database(dbname)
33
+ end
34
+
35
+ # maintain the correspondence between an fs and couch
36
+
37
+ def push_app(appdir, appname)
38
+ libs = []
39
+ viewdir = File.join(appdir,"views")
40
+ attachdir = File.join(appdir,"_attachments")
41
+
42
+ @doc = dir_to_fields(appdir)
43
+ package_shows(@doc["shows"]) if @doc["shows"]
44
+ package_shows(@doc["lists"]) if @doc["lists"]
45
+ package_views(@doc["views"]) if @doc['views']
46
+
47
+ docid = "_design/#{appname}"
48
+ design = @db.get(docid) rescue {}
49
+ design.merge!(@doc)
50
+ design['_id'] = docid
51
+ # design['language'] = lang if lang
52
+ @db.save_doc(design)
53
+ push_directory(attachdir, docid)
54
+ end
55
+
56
+ def dir_to_fields(dir)
57
+ fields = {}
58
+ (Dir["#{dir}/**/*.*"] -
59
+ Dir["#{dir}/_attachments/**/*.*"]).each do |file|
60
+ farray = file.sub(dir, '').sub(/^\//,'').split('/')
61
+ myfield = fields
62
+ while farray.length > 1
63
+ front = farray.shift
64
+ myfield[front] ||= {}
65
+ myfield = myfield[front]
66
+ end
67
+ fname, fext = farray.shift.split('.')
68
+ fguts = File.open(file).read
69
+ if fext == 'json'
70
+ myfield[fname] = JSON.parse(fguts)
71
+ else
72
+ myfield[fname] = fguts
73
+ end
74
+ end
75
+ return fields
76
+ end
77
+
78
+ def push_directory(push_dir, docid=nil)
79
+ docid ||= push_dir.split('/').reverse.find{|part|!part.empty?}
80
+
81
+ pushfiles = Dir["#{push_dir}/**/*.*"].collect do |f|
82
+ {f.split("#{push_dir}/").last => open(f).read}
83
+ end
84
+
85
+ return if pushfiles.empty?
86
+
87
+ @attachments = {}
88
+ @signatures = {}
89
+ pushfiles.each do |file|
90
+ name = file.keys.first
91
+ value = file.values.first
92
+ @signatures[name] = md5(value)
93
+
94
+ @attachments[name] = {
95
+ "data" => value,
96
+ "content_type" => MIMES[name.split('.').last]
97
+ }
98
+ end
99
+
100
+ doc = @db.get(docid) rescue nil
101
+
102
+ unless doc
103
+ say "creating #{docid}"
104
+ @db.save_doc({"_id" => docid, "_attachments" => @attachments, "signatures" => @signatures})
105
+ return
106
+ end
107
+
108
+ doc["signatures"] ||= {}
109
+ doc["_attachments"] ||= {}
110
+ # remove deleted docs
111
+ to_be_removed = doc["signatures"].keys.select do |d|
112
+ !pushfiles.collect{|p| p.keys.first}.include?(d)
113
+ end
114
+
115
+ to_be_removed.each do |p|
116
+ say "deleting #{p}"
117
+ doc["signatures"].delete(p)
118
+ doc["_attachments"].delete(p)
119
+ end
120
+
121
+ # update existing docs:
122
+ doc["signatures"].each do |path, sig|
123
+ if (@signatures[path] == sig)
124
+ say "no change to #{path}. skipping..."
125
+ else
126
+ say "replacing #{path}"
127
+ doc["signatures"][path] = md5(@attachments[path]["data"])
128
+ doc["_attachments"][path].delete("stub")
129
+ doc["_attachments"][path].delete("length")
130
+ doc["_attachments"][path]["data"] = @attachments[path]["data"]
131
+ doc["_attachments"][path].merge!({"data" => @attachments[path]["data"]} )
132
+ end
133
+ end
134
+
135
+ # add in new files
136
+ new_files = pushfiles.select{|d| !doc["signatures"].keys.include?( d.keys.first) }
137
+
138
+ new_files.each do |f|
139
+ say "creating #{f}"
140
+ path = f.keys.first
141
+ content = f.values.first
142
+ doc["signatures"][path] = md5(content)
143
+
144
+ doc["_attachments"][path] = {
145
+ "data" => content,
146
+ "content_type" => MIMES[path.split('.').last]
147
+ }
148
+ end
149
+
150
+ begin
151
+ @db.save_doc(doc)
152
+ rescue Exception => e
153
+ say e.message
154
+ end
155
+ end
156
+
157
+ private
158
+
159
+ def package_shows(funcs)
160
+ apply_lib(funcs)
161
+ end
162
+
163
+ def package_views(views)
164
+ views.each do |view, funcs|
165
+ apply_lib(funcs)
166
+ end
167
+ end
168
+
169
+ def apply_lib(funcs)
170
+ funcs.each do |k,v|
171
+ next unless v.is_a?(String)
172
+ funcs[k] = process_include(process_require(v))
173
+ end
174
+ end
175
+
176
+ # process requires
177
+ def process_require(f_string)
178
+ f_string.gsub /(\/\/|#)\ ?!code (.*)/ do
179
+ fields = $2.split('.')
180
+ library = @doc
181
+ fields.each do |field|
182
+ library = library[field]
183
+ break unless library
184
+ end
185
+ library
186
+ end
187
+ end
188
+
189
+ # process includes
190
+ def process_include(f_string)
191
+ included = {}
192
+ f_string.gsub /(\/\/|#)\ ?!json (.*)/ do
193
+ fields = $2.split('.')
194
+ library = @doc
195
+ include_to = included
196
+ count = fields.length
197
+ fields.each_with_index do |field, i|
198
+ break unless library[field]
199
+ library = library[field]
200
+ # normal case
201
+ if i+1 < count
202
+ include_to[field] = include_to[field] || {}
203
+ include_to = include_to[field]
204
+ else
205
+ # last one
206
+ include_to[field] = library
207
+ end
208
+ end
209
+
210
+ end
211
+ # puts included.inspect
212
+ rval = if included == {}
213
+ f_string
214
+ else
215
+ varstrings = included.collect do |k, v|
216
+ "var #{k} = #{v.to_json};"
217
+ end
218
+ # just replace the first instance of the macro
219
+ f_string.sub /(\/\/|#)\ ?!json (.*)/, varstrings.join("\n")
220
+ end
221
+
222
+ rval
223
+ end
224
+
225
+
226
+ def say words
227
+ puts words if @loud
228
+ end
229
+
230
+ def md5 string
231
+ Digest::MD5.hexdigest(string)
232
+ end
233
+ end
234
+ end
data/lib/cambric.rb CHANGED
@@ -51,7 +51,7 @@ module Cambric
51
51
  end
52
52
 
53
53
  def self.push_design_docs
54
- @databases.keys.each{ |db| push_design_doc_for db.to_s }
54
+ @databases.keys.each{ |db_sym| push_design_doc_for db_sym.to_s }
55
55
  end
56
56
 
57
57
  def self.prepare_databases
@@ -69,7 +69,8 @@ private
69
69
  def self.push_design_doc_for database
70
70
  design_doc_path = File.join @db_dir, database
71
71
  if File.exist?(design_doc_path)
72
- `couchapp push #{design_doc_path} #{@design_doc_name} #{self[database].uri}`
72
+ fm = FileManager.new self[database].name, self[database].host
73
+ fm.push_app design_doc_path, @design_doc_name
73
74
  end
74
75
  end
75
76
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zdzolton-cambric
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zachary Zolton
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-06-09 00:00:00 -07:00
13
+ date: 2009-07-08 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -43,6 +43,7 @@ files:
43
43
  - lib/cambric.rb
44
44
  - lib/cambric/assume_design_doc_name.rb
45
45
  - lib/cambric/configurator.rb
46
+ - lib/cambric/file_manager.rb
46
47
  - lib/cambric/test_helpers.rb
47
48
  - spec/cambric/assume_design_doc_name_spec.rb
48
49
  - spec/cambric/cambric_spec.rb