soca 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/HISTORY +3 -0
  4. data/LICENSE +20 -0
  5. data/README.md +89 -0
  6. data/Rakefile +58 -0
  7. data/bin/soca +5 -0
  8. data/lib/soca.rb +34 -0
  9. data/lib/soca/cli.rb +189 -0
  10. data/lib/soca/plugin.rb +31 -0
  11. data/lib/soca/plugins/compass.rb +24 -0
  12. data/lib/soca/plugins/jim.rb +19 -0
  13. data/lib/soca/pusher.rb +186 -0
  14. data/lib/soca/templates/Jimfile +12 -0
  15. data/lib/soca/templates/config.js.erb +4 -0
  16. data/lib/soca/templates/couchapprc.erb +10 -0
  17. data/lib/soca/templates/css/screen.css +1 -0
  18. data/lib/soca/templates/db/views/by_type/map.js +3 -0
  19. data/lib/soca/templates/hooks/before_build.rb +2 -0
  20. data/lib/soca/templates/index.html.erb +17 -0
  21. data/lib/soca/templates/js/app.js +12 -0
  22. data/lib/soca/templates/js/vendor/jquery-1.4.2.js +6240 -0
  23. data/lib/soca/templates/js/vendor/jquery.couch-0.11.js +668 -0
  24. data/lib/soca/templates/js/vendor/sammy-0.6.1.js +1809 -0
  25. data/lib/soca/templates/js/vendor/sammy.couch-0.1.0.js +122 -0
  26. data/lib/soca/templates/js/vendor/sha1.js +202 -0
  27. data/soca.gemspec +107 -0
  28. data/test/helper.rb +36 -0
  29. data/test/test_soca_cli.rb +120 -0
  30. data/test/test_soca_pusher.rb +79 -0
  31. data/test/testapp/.couchapprc +10 -0
  32. data/test/testapp/Jimfile +11 -0
  33. data/test/testapp/config.js +11 -0
  34. data/test/testapp/css/app.css +3 -0
  35. data/test/testapp/db/views/recent/map.js +5 -0
  36. data/test/testapp/hooks/before_build.rb +1 -0
  37. data/test/testapp/index.html +11 -0
  38. data/test/testapp/js/app.js +5 -0
  39. data/test/testapp/js/bundled.js +8544 -0
  40. data/test/testapp/js/vendor/jquery-1.4.2.js +6240 -0
  41. data/test/testapp/js/vendor/json2.js +478 -0
  42. data/test/testapp/js/vendor/sammy-0.5.4.js +1403 -0
  43. data/test/testapp/js/vendor/sammy.mustache-0.5.4.js +415 -0
  44. data/test/testapp/templates/index.mustache +1 -0
  45. metadata +205 -0
@@ -0,0 +1,122 @@
1
+ (function($, Sammy) {
2
+
3
+ Sammy = Sammy || {};
4
+
5
+ Sammy.Couch = function(app, dbname) {
6
+
7
+ // set the default dbname form the URL
8
+ dbname = dbname || window.location.pathname.split('/')[1];
9
+
10
+ var db = function() {
11
+ if (!dbname) {
12
+ throw("Please define a db to load from");
13
+ }
14
+ return this._db = this._db || $.couch.db(dbname);
15
+ };
16
+
17
+ var timestamp = function() {
18
+ return new Date().getTime();
19
+ };
20
+
21
+ this.db = db();
22
+
23
+ this.createModel = function(type, options) {
24
+ options = $.extend({
25
+ defaultDocument: function() {
26
+ return {
27
+ type: type,
28
+ updated_at: timestamp()
29
+ };
30
+ },
31
+ errorHandler: function(response) {
32
+ app.trigger('error.' + type, {error: response});
33
+ }
34
+ }, options || {});
35
+
36
+ var mergeCallbacks = function(callback) {
37
+ var base = {error: options.errorHandler};
38
+ if ($.isFunction(callback)) {
39
+ return $.extend(base, {success: callback});
40
+ } else {
41
+ return $.extend(base, callback || {});
42
+ }
43
+ };
44
+
45
+ var mergeDefaultDocument = function(doc) {
46
+ return $.extend({}, options.defaultDocument(), doc);
47
+ };
48
+
49
+ var model = {
50
+ timestamp: timestamp,
51
+
52
+ extend: function(obj) {
53
+ $.extend(model, obj);
54
+ },
55
+
56
+ all: function(callback) {
57
+ return app.db.allDocs($.extend(mergeCallbacks(callback), {
58
+ include_docs: true
59
+ }));
60
+ },
61
+
62
+ get: function(id, options, callback) {
63
+ if ($.isFunction(options)) {
64
+ callback = options;
65
+ options = {};
66
+ }
67
+ return app.db.openDoc(id, $.extend(mergeCallbacks(callback), options));
68
+ },
69
+
70
+ create: function(doc, callback) {
71
+ return model.save(mergeDefaultDocument(doc), callback);
72
+ },
73
+
74
+ save: function(doc, callback) {
75
+ if ($.isFunction(model.beforeSave)) {
76
+ doc = model.beforeSave(doc);
77
+ }
78
+ return app.db.saveDoc(doc, mergeCallbacks(callback));
79
+ },
80
+
81
+ update: function(id, doc, callback) {
82
+ model.get(id, function(original_doc) {
83
+ doc = $.extend(original_doc, doc);
84
+ model.save(doc, callback);
85
+ });
86
+ },
87
+
88
+ view: function(name, options, callback) {
89
+ if ($.isFunction(options)) {
90
+ callback = options;
91
+ options = {};
92
+ }
93
+ return app.db.view([dbname, name].join('/'), $.extend(mergeCallbacks(callback), options));
94
+ },
95
+
96
+ viewDocs: function(name, options, callback) {
97
+ if ($.isFunction(options)) {
98
+ callback = options;
99
+ options = {};
100
+ }
101
+ var wrapped_callback = function(json) {
102
+ var docs = [];
103
+ for (var i=0;i<json['rows'].length;i++) {
104
+ docs.push(json['rows'][i]['doc']);
105
+ }
106
+ callback(docs);
107
+ };
108
+ options = $.extend({
109
+ include_docs: true
110
+ }, mergeCallbacks(wrapped_callback), options);
111
+ return app.db.view([dbname, name].join('/'), options);
112
+ }
113
+ };
114
+ return model;
115
+ };
116
+
117
+ this.helpers({
118
+ db: db()
119
+ });
120
+ };
121
+
122
+ })(jQuery, window.Sammy);
@@ -0,0 +1,202 @@
1
+ /*
2
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
3
+ * in FIPS PUB 180-1
4
+ * Version 2.1a Copyright Paul Johnston 2000 - 2002.
5
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
6
+ * Distributed under the BSD License
7
+ * See http://pajhome.org.uk/crypt/md5 for details.
8
+ */
9
+
10
+ /*
11
+ * Configurable variables. You may need to tweak these to be compatible with
12
+ * the server-side, but the defaults work in most cases.
13
+ */
14
+ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
15
+ var b64pad = "="; /* base-64 pad character. "=" for strict RFC compliance */
16
+ var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
17
+
18
+ /*
19
+ * These are the functions you'll usually want to call
20
+ * They take string arguments and return either hex or base-64 encoded strings
21
+ */
22
+ function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
23
+ function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
24
+ function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
25
+ function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
26
+ function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
27
+ function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
28
+
29
+ /*
30
+ * Perform a simple self-test to see if the VM is working
31
+ */
32
+ function sha1_vm_test()
33
+ {
34
+ return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
35
+ }
36
+
37
+ /*
38
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
39
+ */
40
+ function core_sha1(x, len)
41
+ {
42
+ /* append padding */
43
+ x[len >> 5] |= 0x80 << (24 - len % 32);
44
+ x[((len + 64 >> 9) << 4) + 15] = len;
45
+
46
+ var w = Array(80);
47
+ var a = 1732584193;
48
+ var b = -271733879;
49
+ var c = -1732584194;
50
+ var d = 271733878;
51
+ var e = -1009589776;
52
+
53
+ for(var i = 0; i < x.length; i += 16)
54
+ {
55
+ var olda = a;
56
+ var oldb = b;
57
+ var oldc = c;
58
+ var oldd = d;
59
+ var olde = e;
60
+
61
+ for(var j = 0; j < 80; j++)
62
+ {
63
+ if(j < 16) w[j] = x[i + j];
64
+ else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
65
+ var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
66
+ safe_add(safe_add(e, w[j]), sha1_kt(j)));
67
+ e = d;
68
+ d = c;
69
+ c = rol(b, 30);
70
+ b = a;
71
+ a = t;
72
+ }
73
+
74
+ a = safe_add(a, olda);
75
+ b = safe_add(b, oldb);
76
+ c = safe_add(c, oldc);
77
+ d = safe_add(d, oldd);
78
+ e = safe_add(e, olde);
79
+ }
80
+ return Array(a, b, c, d, e);
81
+
82
+ }
83
+
84
+ /*
85
+ * Perform the appropriate triplet combination function for the current
86
+ * iteration
87
+ */
88
+ function sha1_ft(t, b, c, d)
89
+ {
90
+ if(t < 20) return (b & c) | ((~b) & d);
91
+ if(t < 40) return b ^ c ^ d;
92
+ if(t < 60) return (b & c) | (b & d) | (c & d);
93
+ return b ^ c ^ d;
94
+ }
95
+
96
+ /*
97
+ * Determine the appropriate additive constant for the current iteration
98
+ */
99
+ function sha1_kt(t)
100
+ {
101
+ return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
102
+ (t < 60) ? -1894007588 : -899497514;
103
+ }
104
+
105
+ /*
106
+ * Calculate the HMAC-SHA1 of a key and some data
107
+ */
108
+ function core_hmac_sha1(key, data)
109
+ {
110
+ var bkey = str2binb(key);
111
+ if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
112
+
113
+ var ipad = Array(16), opad = Array(16);
114
+ for(var i = 0; i < 16; i++)
115
+ {
116
+ ipad[i] = bkey[i] ^ 0x36363636;
117
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
118
+ }
119
+
120
+ var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
121
+ return core_sha1(opad.concat(hash), 512 + 160);
122
+ }
123
+
124
+ /*
125
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
126
+ * to work around bugs in some JS interpreters.
127
+ */
128
+ function safe_add(x, y)
129
+ {
130
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
131
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
132
+ return (msw << 16) | (lsw & 0xFFFF);
133
+ }
134
+
135
+ /*
136
+ * Bitwise rotate a 32-bit number to the left.
137
+ */
138
+ function rol(num, cnt)
139
+ {
140
+ return (num << cnt) | (num >>> (32 - cnt));
141
+ }
142
+
143
+ /*
144
+ * Convert an 8-bit or 16-bit string to an array of big-endian words
145
+ * In 8-bit function, characters >255 have their hi-byte silently ignored.
146
+ */
147
+ function str2binb(str)
148
+ {
149
+ var bin = Array();
150
+ var mask = (1 << chrsz) - 1;
151
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
152
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
153
+ return bin;
154
+ }
155
+
156
+ /*
157
+ * Convert an array of big-endian words to a string
158
+ */
159
+ function binb2str(bin)
160
+ {
161
+ var str = "";
162
+ var mask = (1 << chrsz) - 1;
163
+ for(var i = 0; i < bin.length * 32; i += chrsz)
164
+ str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
165
+ return str;
166
+ }
167
+
168
+ /*
169
+ * Convert an array of big-endian words to a hex string.
170
+ */
171
+ function binb2hex(binarray)
172
+ {
173
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
174
+ var str = "";
175
+ for(var i = 0; i < binarray.length * 4; i++)
176
+ {
177
+ str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
178
+ hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
179
+ }
180
+ return str;
181
+ }
182
+
183
+ /*
184
+ * Convert an array of big-endian words to a base-64 string
185
+ */
186
+ function binb2b64(binarray)
187
+ {
188
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
189
+ var str = "";
190
+ for(var i = 0; i < binarray.length * 4; i += 3)
191
+ {
192
+ var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16)
193
+ | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
194
+ | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
195
+ for(var j = 0; j < 4; j++)
196
+ {
197
+ if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
198
+ else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
199
+ }
200
+ }
201
+ return str;
202
+ }
@@ -0,0 +1,107 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{soca}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Aaron Quint"]
12
+ s.date = %q{2010-09-26}
13
+ s.default_executable = %q{soca}
14
+ s.description = %q{soca is a different way of writing apps for CouchDB. The structure is up to you.}
15
+ s.email = %q{aaron@quirkey.com}
16
+ s.executables = ["soca"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "HISTORY",
25
+ "LICENSE",
26
+ "README.md",
27
+ "Rakefile",
28
+ "bin/soca",
29
+ "lib/soca.rb",
30
+ "lib/soca/cli.rb",
31
+ "lib/soca/plugin.rb",
32
+ "lib/soca/plugins/compass.rb",
33
+ "lib/soca/plugins/jim.rb",
34
+ "lib/soca/pusher.rb",
35
+ "lib/soca/templates/Jimfile",
36
+ "lib/soca/templates/config.js.erb",
37
+ "lib/soca/templates/couchapprc.erb",
38
+ "lib/soca/templates/css/screen.css",
39
+ "lib/soca/templates/db/views/by_type/map.js",
40
+ "lib/soca/templates/hooks/before_build.rb",
41
+ "lib/soca/templates/index.html.erb",
42
+ "lib/soca/templates/js/app.js",
43
+ "lib/soca/templates/js/vendor/jquery-1.4.2.js",
44
+ "lib/soca/templates/js/vendor/jquery.couch-0.11.js",
45
+ "lib/soca/templates/js/vendor/sammy-0.6.1.js",
46
+ "lib/soca/templates/js/vendor/sammy.couch-0.1.0.js",
47
+ "lib/soca/templates/js/vendor/sha1.js",
48
+ "soca.gemspec",
49
+ "test/helper.rb",
50
+ "test/test_soca_cli.rb",
51
+ "test/test_soca_pusher.rb",
52
+ "test/testapp/.couchapprc",
53
+ "test/testapp/Jimfile",
54
+ "test/testapp/config.js",
55
+ "test/testapp/css/app.css",
56
+ "test/testapp/db/views/recent/map.js",
57
+ "test/testapp/hooks/before_build.rb",
58
+ "test/testapp/index.html",
59
+ "test/testapp/js/app.js",
60
+ "test/testapp/js/bundled.js",
61
+ "test/testapp/js/vendor/jquery-1.4.2.js",
62
+ "test/testapp/js/vendor/json2.js",
63
+ "test/testapp/js/vendor/sammy-0.5.4.js",
64
+ "test/testapp/js/vendor/sammy.mustache-0.5.4.js",
65
+ "test/testapp/templates/index.mustache"
66
+ ]
67
+ s.homepage = %q{http://github.com/quirkey/soca}
68
+ s.rdoc_options = ["--charset=UTF-8"]
69
+ s.require_paths = ["lib"]
70
+ s.rubygems_version = %q{1.3.7}
71
+ s.summary = %q{Sammy on CouchApp}
72
+ s.test_files = [
73
+ "test/helper.rb",
74
+ "test/test_soca_cli.rb",
75
+ "test/test_soca_pusher.rb",
76
+ "test/testapp/hooks/before_build.rb"
77
+ ]
78
+
79
+ if s.respond_to? :specification_version then
80
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
81
+ s.specification_version = 3
82
+
83
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
84
+ s.add_runtime_dependency(%q<json>, ["~> 1.4.6"])
85
+ s.add_runtime_dependency(%q<typhoeus>, ["~> 0.1.31"])
86
+ s.add_runtime_dependency(%q<jim>, ["~> 0.2.3"])
87
+ s.add_runtime_dependency(%q<compass>, ["~> 0.10.5"])
88
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
89
+ s.add_development_dependency(%q<yard>, [">= 0"])
90
+ else
91
+ s.add_dependency(%q<json>, ["~> 1.4.6"])
92
+ s.add_dependency(%q<typhoeus>, ["~> 0.1.31"])
93
+ s.add_dependency(%q<jim>, ["~> 0.2.3"])
94
+ s.add_dependency(%q<compass>, ["~> 0.10.5"])
95
+ s.add_dependency(%q<shoulda>, [">= 0"])
96
+ s.add_dependency(%q<yard>, [">= 0"])
97
+ end
98
+ else
99
+ s.add_dependency(%q<json>, ["~> 1.4.6"])
100
+ s.add_dependency(%q<typhoeus>, ["~> 0.1.31"])
101
+ s.add_dependency(%q<jim>, ["~> 0.2.3"])
102
+ s.add_dependency(%q<compass>, ["~> 0.10.5"])
103
+ s.add_dependency(%q<shoulda>, [">= 0"])
104
+ s.add_dependency(%q<yard>, [">= 0"])
105
+ end
106
+ end
107
+
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'soca'
9
+
10
+ class Test::Unit::TestCase
11
+
12
+ def setup
13
+ @log = StringIO.new
14
+ Soca.logger = Logger.new(@log)
15
+ @test_app_dir = File.expand_path(File.join(File.dirname(__FILE__), 'testapp')) + '/'
16
+ @new_app_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'tmp', 'newapp'))
17
+ FileUtils.rm_rf(@new_app_dir) if File.directory?(@new_app_dir)
18
+ FileUtils.mkdir_p(@new_app_dir)
19
+ end
20
+
21
+ # stolen from the thor specs
22
+ def capture(stream)
23
+ begin
24
+ stream = stream.to_s
25
+ eval "$#{stream} = StringIO.new"
26
+ yield
27
+ result = eval("$#{stream}").string
28
+ ensure
29
+ eval("$#{stream} = #{stream.upcase}")
30
+ end
31
+
32
+ result
33
+ end
34
+ alias :silence :capture
35
+
36
+ end