koda 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/helpers/app_helper.rb +40 -0
- data/lib/helpers/koda_helper.rb +105 -0
- data/lib/helpers/view_helper.rb +146 -0
- data/lib/koda.rb +123 -0
- data/lib/models/hash.rb +29 -0
- data/lib/models/mongo_collection.rb +144 -0
- data/lib/models/mongo_config.rb +22 -0
- data/lib/models/mongo_database.rb +136 -0
- data/lib/models/mongo_document.rb +124 -0
- data/lib/models/mongo_grid.rb +85 -0
- data/lib/models/mongo_media.rb +55 -0
- data/lib/models/user_access_provider.rb +135 -0
- data/lib/models/user_context.rb +19 -0
- data/lib/routes/koda_api.rb +392 -0
- data/lib/routes/koda_site.rb +57 -0
- data/lib/views/console.erb +139 -0
- data/lib/views/explorer.erb +119 -0
- data/lib/views/login.erb +77 -0
- data/lib/views/not_allowed.erb +75 -0
- data/public/koda/Help/DataTypes.txt +82 -0
- data/public/koda/Help/KodaType_Template.js +48 -0
- data/public/koda/apple-touch-icon-114x114-precomposed.png +0 -0
- data/public/koda/apple-touch-icon-144x144-precomposed.png +0 -0
- data/public/koda/apple-touch-icon-57x57-precomposed.png +0 -0
- data/public/koda/apple-touch-icon-72x72-precomposed.png +0 -0
- data/public/koda/apple-touch-icon-precomposed.png +0 -0
- data/public/koda/apple-touch-icon.png +0 -0
- data/public/koda/css/bootstrap-responsive.css +1058 -0
- data/public/koda/css/bootstrap.css +5774 -0
- data/public/koda/css/main.css +288 -0
- data/public/koda/favicon.ico +0 -0
- data/public/koda/fonts/angelina-webfont.eot +0 -0
- data/public/koda/fonts/angelina-webfont.svg +228 -0
- data/public/koda/fonts/angelina-webfont.ttf +0 -0
- data/public/koda/fonts/angelina-webfont.woff +0 -0
- data/public/koda/fonts/coolvetica_rg-webfont.eot +0 -0
- data/public/koda/fonts/coolvetica_rg-webfont.svg +232 -0
- data/public/koda/fonts/coolvetica_rg-webfont.ttf +0 -0
- data/public/koda/fonts/coolvetica_rg-webfont.woff +0 -0
- data/public/koda/fonts/ladyic__-webfont.eot +0 -0
- data/public/koda/fonts/ladyic__-webfont.svg +257 -0
- data/public/koda/fonts/ladyic__-webfont.ttf +0 -0
- data/public/koda/fonts/ladyic__-webfont.woff +0 -0
- data/public/koda/images/ajax-loader.gif +0 -0
- data/public/koda/images/back.png +0 -0
- data/public/koda/images/bg-table-thead.png +0 -0
- data/public/koda/images/big_folder.png +0 -0
- data/public/koda/images/box_file.png +0 -0
- data/public/koda/images/car_add.png +0 -0
- data/public/koda/images/compress.png +0 -0
- data/public/koda/images/database_table.png +0 -0
- data/public/koda/images/feed_add.png +0 -0
- data/public/koda/images/feed_link.png +0 -0
- data/public/koda/images/file.png +0 -0
- data/public/koda/images/folder.png +0 -0
- data/public/koda/images/folder_image.png +0 -0
- data/public/koda/images/glyphicons-halflings-white.png +0 -0
- data/public/koda/images/glyphicons-halflings.png +0 -0
- data/public/koda/images/group_add.png +0 -0
- data/public/koda/images/group_key.png +0 -0
- data/public/koda/images/image_add.png +0 -0
- data/public/koda/images/layout_add.png +0 -0
- data/public/koda/images/package.png +0 -0
- data/public/koda/images/page_white_edit.png +0 -0
- data/public/koda/images/page_white_text.png +0 -0
- data/public/koda/images/photo_add.png +0 -0
- data/public/koda/images/toggle-collapse-dark.png +0 -0
- data/public/koda/images/toggle-collapse-light.png +0 -0
- data/public/koda/images/toggle-expand-dark.png +0 -0
- data/public/koda/images/toggle-expand-light.png +0 -0
- data/public/koda/images/twitter.png +0 -0
- data/public/koda/koda-editors/KodaEditor.js +843 -0
- data/public/koda/koda-editors/collection-editor.html +56 -0
- data/public/koda/koda-editors/generic-editor.css +112 -0
- data/public/koda/koda-editors/generic-editor.html +74 -0
- data/public/koda/koda-editors/koda-editor.css +72 -0
- data/public/koda/koda-editors/twitterfeed-editor.html +90 -0
- data/public/koda/koda-types/_builtin_registration.json +62 -0
- data/public/koda/koda-types/koda-access.json +49 -0
- data/public/koda/koda-types/koda-collection.json +12 -0
- data/public/koda/koda-types/koda-generictext.json +50 -0
- data/public/koda/koda-types/koda-media.json +58 -0
- data/public/koda/koda-types/koda-twitterfeed.json +79 -0
- data/public/koda/koda-types/koda-user.json +71 -0
- data/public/koda/nicEditorIcons.gif +0 -0
- data/public/koda/scripts/Koda.js +1200 -0
- data/public/koda/scripts/lib/DOMAssistant.js +4 -0
- data/public/koda/scripts/lib/modernizr.js +4 -0
- data/public/koda/scripts/lib/respond.js +2 -0
- data/public/koda/scripts/lib/selectivizr.js +5 -0
- data/public/koda/scripts/plugins/bootstrap.js +2027 -0
- data/public/koda/scripts/plugins/box.js +8 -0
- data/public/koda/scripts/plugins/fancybox/blank.gif +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_close.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_loading.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_nav_left.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_nav_right.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_e.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_n.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_ne.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_nw.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_s.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_se.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_sw.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_shadow_w.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_title_left.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_title_main.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_title_over.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancy_title_right.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancybox-x.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancybox-y.png +0 -0
- data/public/koda/scripts/plugins/fancybox/fancybox.png +0 -0
- data/public/koda/scripts/plugins/fancybox/jquery.easing-1.3.pack.js +72 -0
- data/public/koda/scripts/plugins/fancybox/jquery.fancybox-1.3.4.css +359 -0
- data/public/koda/scripts/plugins/fancybox/jquery.fancybox-1.3.4.js +1155 -0
- data/public/koda/scripts/plugins/fancybox/jquery.fancybox-1.3.4.pack.js +46 -0
- data/public/koda/scripts/plugins/fancybox/jquery.mousewheel-3.0.4.pack.js +14 -0
- data/public/koda/scripts/plugins/fileuploader.js +1527 -0
- data/public/koda/scripts/plugins/jquery-class.js +7 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/images/cut.png +0 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/images/door.png +0 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_copy.png +0 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_delete.png +0 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_edit.png +0 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/images/page_white_paste.png +0 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/jquery.contextMenu.css +63 -0
- data/public/koda/scripts/plugins/jquery.contextmenu/jquery.contextMenu.js +211 -0
- data/public/koda/scripts/plugins/jquery.js +2 -0
- data/public/koda/scripts/plugins/json2.js +277 -0
- data/public/koda/scripts/plugins/modernizr.js +2 -0
- data/public/koda/scripts/plugins/nicEdit.js +183 -0
- data/public/koda/scripts/plugins/qunit.js +1448 -0
- data/public/koda/scripts/plugins/spin.js +2 -0
- data/public/koda/scripts/plugins/uploader/README.md +77 -0
- data/public/koda/scripts/plugins/uploader/README.txt +89 -0
- data/public/koda/scripts/plugins/uploader/example/application.js +20 -0
- data/public/koda/scripts/plugins/uploader/example/index.html +109 -0
- data/public/koda/scripts/plugins/uploader/example/style.css +22 -0
- data/public/koda/scripts/plugins/uploader/example/upload.php +313 -0
- data/public/koda/scripts/plugins/uploader/jquery.fileupload-ui.css +100 -0
- data/public/koda/scripts/plugins/uploader/jquery.fileupload-ui.js +642 -0
- data/public/koda/scripts/plugins/uploader/jquery.fileupload.js +711 -0
- data/public/koda/scripts/plugins/uploader/jquery.iframe-transport.js +133 -0
- data/public/koda/scripts/plugins/uploader/pbar-ani.gif +0 -0
- data/public/koda/scripts/plugins/uploader/tests/index.html +115 -0
- data/public/koda/scripts/plugins/uploader/tests/tests.js +1008 -0
- data/public/koda/scripts/require.js +32 -0
- data/public/koda/scripts/specs.js +12 -0
- data/public/koda/scripts/specs/cd-command-spec.js +51 -0
- data/public/koda/scripts/specs/controller-spec.js +95 -0
- data/public/koda/scripts/specs/doubles/mock-command.js +21 -0
- data/public/koda/scripts/specs/doubles/mock-jamservice.js +33 -0
- data/public/koda/scripts/specs/doubles/mock-prompt.js +30 -0
- data/public/koda/scripts/specs/doubles/uiobject-double.js +15 -0
- data/public/koda/scripts/specs/edit-command-spec.js +76 -0
- data/public/koda/scripts/specs/ls-command-spec.js +61 -0
- data/public/koda/scripts/specs/mkdir-command-spec.js +40 -0
- data/public/koda/scripts/specs/peek-command-spec.js +24 -0
- data/public/koda/scripts/specs/remove-command-spec.js +37 -0
- data/public/koda/scripts/specs/service-spec.js +85 -0
- metadata +402 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Application Helpers
|
5
|
+
#
|
6
|
+
# The last line of a method is always the return value
|
7
|
+
#
|
8
|
+
# here you can define any helper methods that are available to your routes and your views
|
9
|
+
#
|
10
|
+
# -----------------------------------------------------
|
11
|
+
# To create a helper method that returns something
|
12
|
+
#
|
13
|
+
# def my_method
|
14
|
+
# 'something'
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# def my_method(param1, param2)
|
18
|
+
# # remember to use doublequotes. single quotes will force a string
|
19
|
+
# "using variables in strings #{param1}, #{param2}"
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# use other helpers
|
23
|
+
#
|
24
|
+
# def is_user_logged_in?
|
25
|
+
# # there are loads of helpers in /koda/helpers that you could use
|
26
|
+
# logged_in?
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
|
30
|
+
helpers do
|
31
|
+
|
32
|
+
def style_link(path)
|
33
|
+
"<link rel=\"StyleSheet\" href=\"#{path}\" type=\"text/css\">"
|
34
|
+
end
|
35
|
+
|
36
|
+
def script_link(path)
|
37
|
+
"<script src=\"#{path}\"></script>"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'dalli'
|
5
|
+
require 'uri'
|
6
|
+
require 'net/https'
|
7
|
+
|
8
|
+
helpers do
|
9
|
+
|
10
|
+
def fetch_linked_docs doc
|
11
|
+
if(doc)
|
12
|
+
|
13
|
+
koda_doc_links = doc['_koda_doc_links']
|
14
|
+
if(doc && koda_doc_links && koda_doc_links != '')
|
15
|
+
|
16
|
+
doc_links = koda_doc_links.split(',')
|
17
|
+
doc['includes'] = []
|
18
|
+
|
19
|
+
doc_links.each do |doc_link|
|
20
|
+
begin
|
21
|
+
if(doc_link.include? 'http')
|
22
|
+
doc_to_include = JSON.parse(get_raw_from_external URI(doc_link))
|
23
|
+
else
|
24
|
+
if(doc_link.include? '/search/')
|
25
|
+
doc_to_include = JSON.parse(get_raw "#{doc_link}")
|
26
|
+
else
|
27
|
+
doc_to_include = JSON.parse(get_raw "#{doc_link}?include=false")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
rescue Exception => e
|
31
|
+
doc_to_include = {'failed' => e.message}
|
32
|
+
end
|
33
|
+
|
34
|
+
key = doc.stripped_document.select{|k,v| v==doc_link}.map{|k,v| k}.first()
|
35
|
+
|
36
|
+
if(doc_to_include)
|
37
|
+
linked_doc_item = {
|
38
|
+
'ref' => key,
|
39
|
+
'document' => doc_to_include
|
40
|
+
}
|
41
|
+
doc['includes'].push linked_doc_item
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def current_user
|
51
|
+
UserContext.current_user
|
52
|
+
end
|
53
|
+
|
54
|
+
def logged_in?
|
55
|
+
@uap.logged_in?
|
56
|
+
end
|
57
|
+
|
58
|
+
def is_admin?
|
59
|
+
@uap.is_admin?
|
60
|
+
end
|
61
|
+
|
62
|
+
def is_allowed?(action, collection_name)
|
63
|
+
@uap.is_allowed? action, collection_name
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_public_read? collection_name
|
67
|
+
@uap.is_public_read? collection_name
|
68
|
+
end
|
69
|
+
|
70
|
+
def log_out
|
71
|
+
@uap.log_out
|
72
|
+
end
|
73
|
+
|
74
|
+
def is_allowed_in_console?
|
75
|
+
@uap.is_allowed_in_console?
|
76
|
+
end
|
77
|
+
|
78
|
+
def is_allowed_in_explorer?
|
79
|
+
@uap.is_allowed_in_explorer?
|
80
|
+
end
|
81
|
+
|
82
|
+
def sign_in_return_url
|
83
|
+
if settings.environment == :development
|
84
|
+
"#{request.host}:#{request.port}"
|
85
|
+
else
|
86
|
+
"#{request.host}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_raw(url)
|
91
|
+
http = Net::HTTP.new(request.host, request.port)
|
92
|
+
request = Net::HTTP::Get.new(url)
|
93
|
+
response = http.request(request)
|
94
|
+
response.body
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_raw_from_external(uri)
|
98
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
99
|
+
http.use_ssl = true if uri.to_s.include? 'https'
|
100
|
+
request = Net::HTTP::Get.new("#{uri.path}?#{uri.query}")
|
101
|
+
response = http.request(request)
|
102
|
+
response.body
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'dalli'
|
3
|
+
require 'uri'
|
4
|
+
require 'rest_client'
|
5
|
+
|
6
|
+
def show_koda(template, locals={})
|
7
|
+
content_type :html
|
8
|
+
options = {:layout => false}.merge(settings.view_options)
|
9
|
+
template = template_for "koda/views/#{template}.#{settings.view_format}"
|
10
|
+
render(settings.view_format, template, options, locals)
|
11
|
+
end
|
12
|
+
|
13
|
+
def show_system(template, locals={})
|
14
|
+
content_type :html
|
15
|
+
options = {:layout => false}.merge(settings.view_options)
|
16
|
+
template = system_view "#{template}.#{settings.view_format}"
|
17
|
+
render(settings.view_format, template, options, locals)
|
18
|
+
end
|
19
|
+
|
20
|
+
def show(template, locals={})
|
21
|
+
content_type :html
|
22
|
+
options = {:layout => true}.merge(settings.view_options)
|
23
|
+
|
24
|
+
@content = get_from_cache
|
25
|
+
|
26
|
+
template = template_for "views/#{template}.#{settings.view_format}"
|
27
|
+
render(settings.view_format, template, settings.view_options, locals)
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_partial(template, locals={})
|
31
|
+
template = template_for "views/#{template}.#{settings.view_format}"
|
32
|
+
options = {:layout => false}.merge(settings.view_options)
|
33
|
+
|
34
|
+
@content = get_from_cache
|
35
|
+
|
36
|
+
content_type :html
|
37
|
+
render(settings.view_format, template, settings.view_options, locals)
|
38
|
+
end
|
39
|
+
|
40
|
+
def render_doc(doc)
|
41
|
+
return "<p>No content has yet been added...</p>\n" if(doc == nil)
|
42
|
+
result = "<dl id='#{doc.alias}'>\n"
|
43
|
+
doc.delete 'alias'
|
44
|
+
|
45
|
+
doc.each do |k,v|
|
46
|
+
if(v.to_s.include? '_koda_media')
|
47
|
+
result += "<img src='#{v}' title='#{k}' \>\n"
|
48
|
+
else
|
49
|
+
result += "<dt>#{k}</dt><dd>#{v}</dd>\n"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
result += "</dl>"
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def model
|
58
|
+
@content
|
59
|
+
end
|
60
|
+
|
61
|
+
def safe(fallback='')
|
62
|
+
begin
|
63
|
+
return yield
|
64
|
+
rescue
|
65
|
+
fallback
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_content
|
70
|
+
|
71
|
+
content = @db_wrapper.flat_file
|
72
|
+
|
73
|
+
if(content)
|
74
|
+
|
75
|
+
content.each do |collection|
|
76
|
+
|
77
|
+
collection_obj = {}
|
78
|
+
|
79
|
+
collection['docs'].each do |doc|
|
80
|
+
k = doc['alias'].gsub(/-/,'_')
|
81
|
+
v = doc.to_obj
|
82
|
+
|
83
|
+
collection_obj.instance_variable_set("@#{k}", v)
|
84
|
+
collection_obj.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
|
85
|
+
end
|
86
|
+
|
87
|
+
collection_obj.class.send(:define_method, "all", proc{self.instance_variables.map {|name| instance_variable_get name }})
|
88
|
+
collection_obj.class.send(:define_method, "where", proc{|&block| self.instance_variables.map {|name| instance_variable_get name }.select{ |o| block.call o}})
|
89
|
+
collection_obj.class.send(:define_method, "single", proc{|&block| self.instance_variables.map {|name| instance_variable_get name }.select{ |o| block.call o}.first})
|
90
|
+
collection_obj.class.send(:define_method, "by_ref", proc{|ref| self.instance_variables.map {|name| instance_variable_get name }.select{ |o| ref.include? o.alias}.first})
|
91
|
+
|
92
|
+
collection_k = collection['collection']
|
93
|
+
collection_v = collection_obj
|
94
|
+
|
95
|
+
content.instance_variable_set("@#{collection_k}", collection_v)
|
96
|
+
content.class.send(:define_method, collection_k, proc{self.instance_variable_get("@#{collection_k}")})
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
return content
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
{}
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
def refresh_cache(time_to_live=settings.long_ttl)
|
109
|
+
key = "full_cache"
|
110
|
+
|
111
|
+
if(settings.enable_cache)
|
112
|
+
settings.cache.delete key
|
113
|
+
settings.cache.set(key, create_content, ttl=time_to_live+rand(100))
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_from_cache(time_to_live=settings.long_ttl)
|
118
|
+
|
119
|
+
key = "full_cache"
|
120
|
+
|
121
|
+
if(!settings.enable_cache)
|
122
|
+
return create_content
|
123
|
+
end
|
124
|
+
|
125
|
+
if(settings.cache.get(key) == nil)
|
126
|
+
settings.cache.set(key, create_content, ttl=time_to_live+rand(100))
|
127
|
+
end
|
128
|
+
|
129
|
+
return settings.cache.get(key)
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def template_for(path)
|
136
|
+
return nil unless File.exists?(path)
|
137
|
+
File.open(path) { |f| f.read }
|
138
|
+
end
|
139
|
+
|
140
|
+
alias user_view template_for
|
141
|
+
|
142
|
+
|
143
|
+
def system_view(path)
|
144
|
+
path = File.dirname(__FILE__)+ '/../views/' + path.to_s
|
145
|
+
template_for path
|
146
|
+
end
|
data/lib/koda.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'json'
|
4
|
+
require 'sinatra/jsonp'
|
5
|
+
require 'rack-methodoverride-with-params'
|
6
|
+
require 'erb'
|
7
|
+
require 'net/http'
|
8
|
+
require 'rest_client'
|
9
|
+
require 'dalli'
|
10
|
+
|
11
|
+
#
|
12
|
+
# Register all models
|
13
|
+
#
|
14
|
+
Dir[File.dirname(__FILE__) + "/models/*.rb"].each {|file| require file }
|
15
|
+
|
16
|
+
#
|
17
|
+
# Register Routes (don't fiddle with the order)
|
18
|
+
#
|
19
|
+
require File.join(File.dirname(__FILE__), %w[/routes/koda_api.rb])
|
20
|
+
require File.join(File.dirname(__FILE__), %w[/routes/koda_site.rb])
|
21
|
+
|
22
|
+
#
|
23
|
+
# Register other helpers and routes
|
24
|
+
#
|
25
|
+
Dir[File.dirname(__FILE__) + "/helpers/*.rb"].each {|file| require file }
|
26
|
+
|
27
|
+
|
28
|
+
#
|
29
|
+
# Main Sinatra Application Class
|
30
|
+
#
|
31
|
+
class KodaApp
|
32
|
+
|
33
|
+
use Rack::MethodOverrideWithParams
|
34
|
+
|
35
|
+
configure do
|
36
|
+
class << Sinatra::Base
|
37
|
+
def options(path, opts={}, &block)
|
38
|
+
route 'OPTIONS', path, opts, &block
|
39
|
+
end
|
40
|
+
end
|
41
|
+
Sinatra::Delegator.delegate :options
|
42
|
+
end
|
43
|
+
|
44
|
+
before do
|
45
|
+
content_type :json
|
46
|
+
response['Access-Control-Allow-Origin'] = '*'
|
47
|
+
response['Access-Control-Allow-Methods'] = 'PUT, DELETE, GET, POST, HEADER, OPTIONS'
|
48
|
+
response['Access-Control-Allow-Headers'] = 'content-type'
|
49
|
+
|
50
|
+
if (@env['HTTP_CACHE_CONTROL'] == 'no-cache')
|
51
|
+
response['Cache-Control'] = 'no-cache'
|
52
|
+
response['Pragma'] = 'no-cache'
|
53
|
+
expires = -1
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# If you need to add database configuration other than local or mongolab
|
58
|
+
# Edit the MongoConfig class
|
59
|
+
#
|
60
|
+
db = MongoConfig::GetMongoDatabase()
|
61
|
+
@db_wrapper = MongoDatabase.new db
|
62
|
+
@grid_wrapper = MongoGrid.new(MongoConfig::GetGridFS(), @db_wrapper.collection('_koda_meta'))
|
63
|
+
|
64
|
+
#
|
65
|
+
# Initialise the Usercontext and set the default UserAccessProvider
|
66
|
+
#
|
67
|
+
UserContext.user_bag = session
|
68
|
+
@uap = UserAccessProvider.new(@db_wrapper)
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
set :protection, :except => [:remote_token, :frame_options, :json_csrf]
|
77
|
+
set :public_folder, File.dirname(__FILE__) + '/public'
|
78
|
+
|
79
|
+
# --------------------------------------------------------------------------
|
80
|
+
# Sinatra View Options (don't modify)
|
81
|
+
# --------------------------------------------------------------------------
|
82
|
+
set :view_format, :erb
|
83
|
+
set :view_options, { :escape_html => true }
|
84
|
+
|
85
|
+
# --------------------------------------------------------------------------
|
86
|
+
# This is a workaround for Cedar apps where production ENV var not being set
|
87
|
+
# Please create an environment var on Heroku and set it to production
|
88
|
+
# --------------------------------------------------------------------------
|
89
|
+
if ENV['ENVIRONMENT']
|
90
|
+
set :environment, ENV['ENVIRONMENT']
|
91
|
+
end
|
92
|
+
|
93
|
+
# --------------------------------------------------------------------------
|
94
|
+
# Cache documents until they are changed (recommended for production)
|
95
|
+
# To Use, set this env var to true
|
96
|
+
# --------------------------------------------------------------------------
|
97
|
+
if ENV['ENABLE_CACHE']
|
98
|
+
set :enable_cache, ENV['ENABLE_CACHE']
|
99
|
+
else
|
100
|
+
set :enable_cache, false
|
101
|
+
end
|
102
|
+
|
103
|
+
# --------------------------------------------------------------------------
|
104
|
+
# Sign up to Janrain Engage and paste your api key here
|
105
|
+
# --------------------------------------------------------------------------
|
106
|
+
set :janrain_api_key, "6c7c4318166d62ad9416231aedca6385e7d7978f"
|
107
|
+
|
108
|
+
# --------------------------------------------------------------------------
|
109
|
+
# Dalli (memcache) settings
|
110
|
+
# --------------------------------------------------------------------------
|
111
|
+
set :cache, Dalli::Client.new
|
112
|
+
set :short_ttl, 400
|
113
|
+
set :long_ttl, 4600
|
114
|
+
|
115
|
+
# --------------------------------------------------------------------------
|
116
|
+
# This is needed for janrain auth
|
117
|
+
# --------------------------------------------------------------------------
|
118
|
+
set :sessions, true
|
119
|
+
|
120
|
+
# --------------------------------------------------------------------------
|
121
|
+
# This is so shotgun keeps session vars
|
122
|
+
# --------------------------------------------------------------------------
|
123
|
+
set :session_secret, "something"
|
data/lib/models/hash.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
class ::Hash
|
2
|
+
|
3
|
+
# add keys to hash
|
4
|
+
def to_obj
|
5
|
+
self.each do |k,v|
|
6
|
+
if v.kind_of? Hash
|
7
|
+
v.to_obj
|
8
|
+
end
|
9
|
+
k=k.gsub(/\.|\s|-|\/|\'/, '_').downcase.to_sym
|
10
|
+
|
11
|
+
## create and initialize an instance variable for this key/value pair
|
12
|
+
self.instance_variable_set("@#{k}", v)
|
13
|
+
|
14
|
+
## create the getter that returns the instance variable
|
15
|
+
self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
|
16
|
+
|
17
|
+
## create the setter that sets the instance variable
|
18
|
+
self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})
|
19
|
+
end
|
20
|
+
return self
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(name)
|
24
|
+
return self[name] if key? name
|
25
|
+
self.each { |k,v| return v if k.to_s.to_sym == name }
|
26
|
+
super.method_missing name
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[mongo_document])
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
class MongoCollection
|
5
|
+
def initialize collection
|
6
|
+
@collection = collection
|
7
|
+
end
|
8
|
+
|
9
|
+
def resource_urls
|
10
|
+
@collection.find.map{|doc| (create_document_wrapper doc).url}
|
11
|
+
end
|
12
|
+
|
13
|
+
def resource_links take=nil, skip=nil, sort=nil
|
14
|
+
resource_links_from_docs @collection.find({},build_options(take, skip, sort)).map
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource_links_no_hidden take=nil, skip=nil, sort=nil
|
18
|
+
resource_links_from_docs @collection.find({ '$or'=> [{'_koda_hidden_file'=>nil},{'_koda_hidden_file'=>false}] },build_options(take, skip, sort)).map
|
19
|
+
end
|
20
|
+
|
21
|
+
def content_links take=nil, skip=nil, sort=nil
|
22
|
+
content_links_from_docs @collection.find({ '$or'=> [{'_koda_hidden_file'=>nil},{'_koda_hidden_file'=>false}] },build_options(take, skip, sort)).map
|
23
|
+
end
|
24
|
+
|
25
|
+
def find_document doc_ref
|
26
|
+
doc = create_document_wrapper @collection.find_one("alias"=>doc_ref)
|
27
|
+
if (doc == nil)
|
28
|
+
begin
|
29
|
+
bsonid = BSON::ObjectId.from_string doc_ref
|
30
|
+
doc = create_document_wrapper @collection.find_one(bsonid)
|
31
|
+
rescue
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
doc
|
36
|
+
end
|
37
|
+
|
38
|
+
def query query_map, take=nil, skip=nil, sort=nil
|
39
|
+
content_links_from_docs @collection.find(query_map, build_options(take, skip, sort))
|
40
|
+
end
|
41
|
+
|
42
|
+
def save_document raw_resource, ref=nil
|
43
|
+
|
44
|
+
if(raw_resource['linked_documents'] != nil)
|
45
|
+
raw_resource.delete 'linked_documents'
|
46
|
+
end
|
47
|
+
|
48
|
+
if !(ref==nil)
|
49
|
+
existing_doc = find_document(ref)
|
50
|
+
end
|
51
|
+
|
52
|
+
if !(existing_doc == nil)
|
53
|
+
updated_doc = MongoDocument.new raw_resource, @collection.name, existing_doc.id, Time.now.httpdate
|
54
|
+
@collection.save(updated_doc.raw_document)
|
55
|
+
else
|
56
|
+
new_id = @collection.insert(raw_resource)
|
57
|
+
|
58
|
+
if(raw_resource['_koda_indexes'] && raw_resource['_koda_indexes'] != '')
|
59
|
+
indexes = raw_resource['_koda_indexes'].split(',')
|
60
|
+
index_collection = []
|
61
|
+
indexes.each do |index|
|
62
|
+
index_collection.push [index, Mongo::ASCENDING]
|
63
|
+
end
|
64
|
+
@collection.ensure_index index_collection
|
65
|
+
end
|
66
|
+
|
67
|
+
updated_doc = MongoDocument.new raw_resource, @collection.name, new_id, Time.now.httpdate
|
68
|
+
|
69
|
+
if(ref and updated_doc.ref != ref)
|
70
|
+
updated_doc.ref = ref
|
71
|
+
@collection.save(raw_resource)
|
72
|
+
end
|
73
|
+
|
74
|
+
updated_doc.is_new = true
|
75
|
+
end
|
76
|
+
|
77
|
+
updated_doc
|
78
|
+
end
|
79
|
+
|
80
|
+
def delete_document ref
|
81
|
+
existing_doc = find_document(ref)
|
82
|
+
|
83
|
+
if (existing_doc)
|
84
|
+
@collection.remove('_id' => existing_doc.id)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def delete
|
89
|
+
@collection.drop
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def resource_links_from_docs docs
|
95
|
+
docs.map do |doc|
|
96
|
+
doc_wrapper = create_document_wrapper doc
|
97
|
+
{
|
98
|
+
'href' => doc_wrapper.url,
|
99
|
+
'_koda_type' => doc_wrapper.type,
|
100
|
+
'rel' => 'full',
|
101
|
+
'title' => doc_wrapper.title,
|
102
|
+
"alias" => doc_wrapper.ref,
|
103
|
+
'_koda_hidden' => doc_wrapper.hidden,
|
104
|
+
'date_created' => doc_wrapper.date_created
|
105
|
+
}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def content_links_from_docs docs
|
110
|
+
docs.map do |doc|
|
111
|
+
doc_wrapper = create_document_wrapper doc
|
112
|
+
{
|
113
|
+
'href' => doc_wrapper.url.gsub(/api/, "content"),
|
114
|
+
'title' => doc_wrapper.title,
|
115
|
+
'alias' => doc_wrapper.ref,
|
116
|
+
'date_created' => doc_wrapper.date_created
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def build_options take, skip, sort
|
122
|
+
options = {}
|
123
|
+
options[:limit] = take.to_i if take != nil
|
124
|
+
options[:skip] = skip.to_i if skip != nil
|
125
|
+
|
126
|
+
if (sort != nil)
|
127
|
+
sort_array = sort.to_a
|
128
|
+
sort_expression = sort_array[0][0]
|
129
|
+
sort_order = sort_array[0][1] == "desc" ? Mongo::DESCENDING : Mongo::ASCENDING
|
130
|
+
|
131
|
+
options[:sort] = [sort_expression, sort_order]
|
132
|
+
end
|
133
|
+
|
134
|
+
options
|
135
|
+
end
|
136
|
+
|
137
|
+
def create_document_wrapper(doc)
|
138
|
+
if !(doc==nil)
|
139
|
+
doc_wrapper=MongoDocument.new doc, @collection.name
|
140
|
+
end
|
141
|
+
doc_wrapper
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|