koda 0.0.8
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/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
|