mongo_fe 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/.DS_Store +0 -0
- data/.gitignore +34 -0
- data/.rspec +2 -0
- data/CHANGES.md +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +138 -0
- data/LICENSE +22 -0
- data/Procfile +2 -0
- data/README.md +72 -0
- data/Rakefile +14 -0
- data/TODO.tasks +9 -0
- data/bin/config.ru +28 -0
- data/bin/mongofe +54 -0
- data/lib/mongo_fe/application_controller.rb +91 -0
- data/lib/mongo_fe/controllers/collections_controller.rb +278 -0
- data/lib/mongo_fe/controllers/databases_controller.rb +94 -0
- data/lib/mongo_fe/helpers/helpers.rb +128 -0
- data/lib/mongo_fe/public/app/application.js +3 -0
- data/lib/mongo_fe/public/bootstrap/css/bootstrap-responsive.css +567 -0
- data/lib/mongo_fe/public/bootstrap/css/bootstrap.css +3380 -0
- data/lib/mongo_fe/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/lib/mongo_fe/public/bootstrap/img/glyphicons-halflings.png +0 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-alert.js +91 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-button.js +98 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-carousel.js +154 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-collapse.js +136 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-dropdown.js +92 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-modal.js +209 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-popover.js +95 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-scrollspy.js +125 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-tab.js +130 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-tooltip.js +270 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-transition.js +51 -0
- data/lib/mongo_fe/public/bootstrap/js/basic/bootstrap-typeahead.js +271 -0
- data/lib/mongo_fe/public/bootstrap/js/bootstrap.js +1722 -0
- data/lib/mongo_fe/public/bootstrap/js/bootstrap.min.js +1 -0
- data/lib/mongo_fe/public/bootstrap/js/jquery.js +9252 -0
- data/lib/mongo_fe/public/bootstrap/js/underscore-min.js +32 -0
- data/lib/mongo_fe/public/bootstrap/js/underscore.js +1059 -0
- data/lib/mongo_fe/public/css/digg_pagination.css +28 -0
- data/lib/mongo_fe/public/css/jsoneditor.css +70 -0
- data/lib/mongo_fe/public/css/styles.css +11 -0
- data/lib/mongo_fe/public/images/missing_avatar_small.png +0 -0
- data/lib/mongo_fe/public/js/collection-tools.js +63 -0
- data/lib/mongo_fe/public/js/db-tools.js +45 -0
- data/lib/mongo_fe/public/js/jsoneditor/jquery.jsoneditor.min.LICENSE +20 -0
- data/lib/mongo_fe/public/js/jsoneditor/jquery.jsoneditor.min.js +6 -0
- data/lib/mongo_fe/public/js/jsoneditor/json2.js +482 -0
- data/lib/mongo_fe/version.rb +6 -0
- data/lib/mongo_fe/views/collections/_document_attributes.haml +6 -0
- data/lib/mongo_fe/views/collections/_documents.haml +35 -0
- data/lib/mongo_fe/views/collections/_documents_page.haml +82 -0
- data/lib/mongo_fe/views/collections/_indexes.haml +76 -0
- data/lib/mongo_fe/views/collections/index.haml +80 -0
- data/lib/mongo_fe/views/databases/_list_users.haml +27 -0
- data/lib/mongo_fe/views/databases/info.haml +80 -0
- data/lib/mongo_fe/views/footer.haml +4 -0
- data/lib/mongo_fe/views/index.haml +7 -0
- data/lib/mongo_fe/views/layout.haml +148 -0
- data/lib/mongo_fe/views/navbar.haml +17 -0
- data/lib/mongo_fe.rb +170 -0
- data/mongo_fe.gemspec +50 -0
- data/screens/example_db_view.png +0 -0
- data/screens/example_doc_view.png +0 -0
- data/screens/example_indexes.png +0 -0
- data/spec/config_spec.rb +17 -0
- data/spec/controllers/collections_controller_spec.rb +151 -0
- data/spec/controllers/db_controller_spec.rb +69 -0
- data/spec/factories/factories.rb +19 -0
- data/spec/spec_helper.rb +88 -0
- metadata +559 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "json"
|
|
3
|
+
require File.dirname(__FILE__) + '/../application_controller'
|
|
4
|
+
require 'will_paginate'
|
|
5
|
+
require 'will_paginate/view_helpers/sinatra'
|
|
6
|
+
require "will_paginate/bootstrap"
|
|
7
|
+
|
|
8
|
+
module MongoFe
|
|
9
|
+
# This controller works as a collection manager for the current db, a database specified by
|
|
10
|
+
# name as a REST parameter.
|
|
11
|
+
|
|
12
|
+
class CollectionsController < ApplicationController
|
|
13
|
+
namespace '/databases/:db_name/collections' do
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
session[:db]=params[:db_name]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
get "/?" do
|
|
20
|
+
haml :'/collections/index'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
get "/:collection_name/?" do
|
|
24
|
+
|
|
25
|
+
collection_name = params[:collection_name]
|
|
26
|
+
|
|
27
|
+
unless collection_name.nil?
|
|
28
|
+
session[:collection] = collection_name
|
|
29
|
+
@collection = current_db.collection collection_name
|
|
30
|
+
@indexes = @collection.index_information
|
|
31
|
+
@page = params[:page].to_i || 1
|
|
32
|
+
@query= session[:query]
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
@total, @documents = MongoFe::MongoDB::SearchDocuments.new(current_db, @collection).list(@query, @page, 10)
|
|
36
|
+
flash_search_results @query, @total
|
|
37
|
+
rescue => e
|
|
38
|
+
session[:query] = nil
|
|
39
|
+
@total, @documents = MongoFe::MongoDB::SearchDocuments.new(current_db, @collection).list(nil, 1, 10)
|
|
40
|
+
|
|
41
|
+
flash[:error] = "Resetting to find all. MongoDB error: #{e.message}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
haml :'/collections/index'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
post "/?" do
|
|
50
|
+
if (collection_name=params[:collection_name])
|
|
51
|
+
current_db.create_collection(collection_name)
|
|
52
|
+
flash[:notice] = "#{collection_name}, successfully created!"
|
|
53
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_name}"
|
|
54
|
+
else
|
|
55
|
+
flash[:error] = "Error: you must provide a collection name."
|
|
56
|
+
redirect "/databases/#{current_db.name}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
post "/:collection_name/search/?" do |db_name, collection_name|
|
|
61
|
+
|
|
62
|
+
if params[:reset_query].nil?
|
|
63
|
+
json_query = params[:json_query].empty? ? '{}' : params[:json_query].gsub(/'/, "\"")
|
|
64
|
+
json_query_show = params[:json_query_show]
|
|
65
|
+
json_query_sort = params[:json_query_sort]
|
|
66
|
+
|
|
67
|
+
begin
|
|
68
|
+
@json_query = JSON.parse json_query
|
|
69
|
+
puts "{query}: #{@json_query.inspect}"
|
|
70
|
+
session[:query] = [@json_query, json_query_show, json_query_sort]
|
|
71
|
+
rescue => e
|
|
72
|
+
flash[:error] = "Invalid query; #{e.message}"
|
|
73
|
+
end
|
|
74
|
+
else
|
|
75
|
+
session[:query] = nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_name}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
delete "/:collection_name/documents*" do |db_name, collection_name, doc_id|
|
|
82
|
+
if (doc_id = params[:doc_id])
|
|
83
|
+
begin
|
|
84
|
+
collection = current_db.collection collection_name
|
|
85
|
+
collection.remove(:_id => BSON::ObjectId.from_string(doc_id))
|
|
86
|
+
flash[:notice] = "Document id: #{doc_id}, deleted from: #{db_name}.#{collection.name}"
|
|
87
|
+
rescue => e
|
|
88
|
+
flash[:error] = "Cannot delete document id: #{doc_id}, from: #{db_name}.#{collection_name}; #{e.message}"
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
flash[:error] = "The document id must be specified"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_name}"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
put "/:collection_name/documents*" do |db_name, collection_name, z|
|
|
98
|
+
if (doc_id = params[:doc_id])
|
|
99
|
+
begin
|
|
100
|
+
@collection = current_db.collection collection_name
|
|
101
|
+
id = BSON::ObjectId.from_string(doc_id)
|
|
102
|
+
r = @collection.find(:_id => id).to_a
|
|
103
|
+
raise "this document is missing!" if r.nil?
|
|
104
|
+
|
|
105
|
+
begin
|
|
106
|
+
if (doc=params[:json_doc_attributes])
|
|
107
|
+
begin
|
|
108
|
+
@doc_id = collection.update({"_id" => id}, JSON.parse(doc)) # rewrite the doc; in the future will use an atomic operator
|
|
109
|
+
flash[:notice] = "Document id: #{doc_id}, updated"
|
|
110
|
+
rescue => e
|
|
111
|
+
raise "Invalid JSON structure: #{e.message}"
|
|
112
|
+
end
|
|
113
|
+
else
|
|
114
|
+
raise "Invalid document."
|
|
115
|
+
end
|
|
116
|
+
rescue => e
|
|
117
|
+
flash[:error] = "Cannot update document; #{e.message}"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
rescue => e
|
|
121
|
+
flash[:error] = "Cannot update the document with id: #{doc_id}; #{e.message}"
|
|
122
|
+
end
|
|
123
|
+
else
|
|
124
|
+
flash[:error] = "The document id must be specified"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_name}"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# create a new index
|
|
131
|
+
post "/:collection_name/indexes*" do |db_name, collection_name, z|
|
|
132
|
+
@collection = current_db.collection collection_name
|
|
133
|
+
session[:collection] = @collection.name
|
|
134
|
+
|
|
135
|
+
unique = !params[:unique].nil? && params[:unique]
|
|
136
|
+
sparse = !params[:sparse].nil? && params[:sparse]
|
|
137
|
+
|
|
138
|
+
if (fields = params[:index_fields])
|
|
139
|
+
begin
|
|
140
|
+
index_name = @collection.create_index(MongoFe::Utils.split_index_specs(fields), {:unique => unique, :sparse => sparse})
|
|
141
|
+
|
|
142
|
+
flash[:notice]="The index: '#{index_name}' was successfully created"
|
|
143
|
+
rescue => e
|
|
144
|
+
flash[:error]="Cannot create the index; #{e.message}"
|
|
145
|
+
end
|
|
146
|
+
else
|
|
147
|
+
flash[:error]="Specify either a single field name or an array of field name, direction pairs"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_name}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# delete an existing index
|
|
155
|
+
#
|
|
156
|
+
delete "/:collection_name/indexes*" do |db_name, collection_name, z|
|
|
157
|
+
@collection = current_db.collection collection_name
|
|
158
|
+
|
|
159
|
+
if (index_name = params[:index_name])
|
|
160
|
+
begin
|
|
161
|
+
@collection.drop_index index_name
|
|
162
|
+
flash[:notice] = "The index: '#{index_name}', was deleted successfully."
|
|
163
|
+
rescue => e
|
|
164
|
+
flash[:error] = "The index: '#{index_name}', cannot be deleted; #{e.message}"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
else
|
|
168
|
+
flash[:error] = "Please specify the index name."
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
session[:collection] = @collection.name
|
|
172
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_name}"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# create a new document
|
|
177
|
+
#
|
|
178
|
+
post "/:collection_name/documents*" do
|
|
179
|
+
@collection = current_db.collection(params[:collection_name])
|
|
180
|
+
|
|
181
|
+
if @collection.nil?
|
|
182
|
+
flash[:error] = "Error: you must provide a valid collection name."
|
|
183
|
+
redirect "/databases/#{current_db.name}"
|
|
184
|
+
else
|
|
185
|
+
session[:collection] = @collection.name # move this and the one above to a before or such
|
|
186
|
+
|
|
187
|
+
begin
|
|
188
|
+
if (doc=params[:json_doc_attributes])
|
|
189
|
+
begin
|
|
190
|
+
@doc_id = @collection.insert(JSON.parse(doc))
|
|
191
|
+
flash[:notice] = "Document id: #{@doc_id.to_s}, added to: #{current_db.name}.#{@collection.name}"
|
|
192
|
+
rescue => e
|
|
193
|
+
raise "Invalid JSON structure; #{e.message}"
|
|
194
|
+
end
|
|
195
|
+
else
|
|
196
|
+
raise "Invalid document."
|
|
197
|
+
end
|
|
198
|
+
rescue => e
|
|
199
|
+
flash[:error] = "Cannot insert document; error: #{e.message}"
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
unless @collection.nil?
|
|
205
|
+
@page = params[:page].to_i || 1
|
|
206
|
+
@query= session[:query]
|
|
207
|
+
|
|
208
|
+
begin
|
|
209
|
+
@total, @documents = MongoFe::MongoDB::SearchDocuments.new(current_db, @collection).list(@query, @page, 10)
|
|
210
|
+
flash_search_results @query, @total
|
|
211
|
+
rescue => e
|
|
212
|
+
session[:query] = nil
|
|
213
|
+
@total, @documents = MongoFe::MongoDB::SearchDocuments.new(current_db, @collection).list(nil, 1, 10)
|
|
214
|
+
|
|
215
|
+
flash[:error] = "Resetting to find all. Cause: #{e.message}"
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
haml :'/collections/index'
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
put "/:collection_name/?" do
|
|
224
|
+
if (collection_name=params[:collection_name])
|
|
225
|
+
collection = current_db.collection(collection_name)
|
|
226
|
+
|
|
227
|
+
if collection.nil?
|
|
228
|
+
flash[:error] = "The db: #{current_db.name} doesn't know this collection: #{collection_name}"
|
|
229
|
+
else
|
|
230
|
+
if (collection_new_name = params[:collection_new_name])
|
|
231
|
+
|
|
232
|
+
begin
|
|
233
|
+
current_db.rename_collection(collection_name, collection_new_name)
|
|
234
|
+
flash[:notice] = "Collection: #{collection_name}, successfully renamed to: #{collection_new_name}"
|
|
235
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_new_name}"
|
|
236
|
+
rescue => e
|
|
237
|
+
flash[:error] = "Cannot rename: #{collection_name}, to: #{collection_new_name}; error: #{e.message}"
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
else
|
|
241
|
+
flash[:error] = "You must provide a collection name."
|
|
242
|
+
end
|
|
243
|
+
redirect "/databases/#{current_db.name}/collections/#{collection_name}"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
else
|
|
247
|
+
flash[:error] = "Error: you must provide a collection name."
|
|
248
|
+
redirect "/databases/#{current_db.name}"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
delete "/:collection_name/?" do
|
|
253
|
+
db=current_db
|
|
254
|
+
if (collection_name=params[:collection_name])
|
|
255
|
+
if (collection = db.collection(collection_name))
|
|
256
|
+
begin
|
|
257
|
+
collection.drop
|
|
258
|
+
flash[:notice] = "#{collection_name}, deleted."
|
|
259
|
+
rescue => e
|
|
260
|
+
flash[:error] = "Error: #{e.message}, while trying to delete the collection: #{collection_name}"
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
else
|
|
264
|
+
flash[:error] = "Error: you must provide a collection name."
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
redirect "/databases/#{db.name}"
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
private
|
|
273
|
+
def flash_search_results(q, total)
|
|
274
|
+
flash[:notice]="query: #{query.string}<br/>#{total} document(s) found." unless (q.nil? || query.string.start_with?("ex."))
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongo"
|
|
3
|
+
require File.dirname(__FILE__) + '/../application_controller'
|
|
4
|
+
|
|
5
|
+
module MongoFe
|
|
6
|
+
class DatabasesController < ApplicationController
|
|
7
|
+
|
|
8
|
+
get '/databases/?' do
|
|
9
|
+
"Move along, nothing to see here!"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# info about a specific database
|
|
13
|
+
get '/databases/:name/?' do
|
|
14
|
+
db_name = params[:name]
|
|
15
|
+
begin
|
|
16
|
+
@db = MongoFe::MongoDB.use(db_name)
|
|
17
|
+
session[:db] = db_name
|
|
18
|
+
session[:collection] = nil
|
|
19
|
+
# flash[:notice] = "DB Selected: #{db_name}. <a href='/databases/#{db_name}/info'>More info?</a>"
|
|
20
|
+
haml :'/databases/info'
|
|
21
|
+
rescue => e
|
|
22
|
+
session[:db]=nil
|
|
23
|
+
flash[:error] = "You must provide a database name; #{e.message}"
|
|
24
|
+
redirect "/"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# create a new database
|
|
29
|
+
post '/databases/?' do
|
|
30
|
+
if (d=params[:name])
|
|
31
|
+
db = MongoFe::MongoDB.use(d)
|
|
32
|
+
session[:db]=d
|
|
33
|
+
flash[:notice] = "A new database: `#{d}`, was created."
|
|
34
|
+
redirect "/databases/#{d}"
|
|
35
|
+
else
|
|
36
|
+
flash[:error] = "Error: you must provide a database name."
|
|
37
|
+
haml :index
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Delete database
|
|
42
|
+
delete '/databases/:name/?' do |d|
|
|
43
|
+
if d
|
|
44
|
+
begin
|
|
45
|
+
MongoFe::MongoDB.connection.drop_database(d)
|
|
46
|
+
flash[:notice] = "Database: #{d} was deleted."
|
|
47
|
+
session[:db]=nil
|
|
48
|
+
rescue => e
|
|
49
|
+
flash[:error] = "Error: #{e.message }; The database: `#{d}` was not deleted."
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
flash[:notice] = "Error: you must provide a database name."
|
|
53
|
+
end
|
|
54
|
+
haml :index
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# create a new database user
|
|
58
|
+
post '/databases/:name/users/?' do |d|
|
|
59
|
+
if d && username=params[:username]
|
|
60
|
+
db = MongoFe::MongoDB.use(d)
|
|
61
|
+
if db.find_user(username)
|
|
62
|
+
flash[:error] = "the user: '#{username}' is already defined."
|
|
63
|
+
else
|
|
64
|
+
is_readonly = params[:readonly].nil? ? false : true
|
|
65
|
+
db.add_user(username, params[:password], is_readonly)
|
|
66
|
+
flash[:notice] = "User: '#{username}', was added successfully."
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
flash[:error] = "you must provide a user name."
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
redirect "/databases/#{d}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# delete an exiting user
|
|
76
|
+
delete '/databases/:name/users/?' do |d|
|
|
77
|
+
if d && username=params[:username]
|
|
78
|
+
db = MongoFe::MongoDB.use(d)
|
|
79
|
+
if db.find_user(username)
|
|
80
|
+
db.remove_user(username)
|
|
81
|
+
flash[:notice] = "User deleted: '#{username}'"
|
|
82
|
+
else
|
|
83
|
+
flash[:error] = "Not a valid username: '#{username}'"
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
flash[:error] = "Please provide a user name."
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
redirect "/databases/#{d}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "bson"
|
|
3
|
+
require 'will_paginate'
|
|
4
|
+
require 'will_paginate/view_helpers/base'
|
|
5
|
+
require 'will_paginate/view_helpers/link_renderer'
|
|
6
|
+
|
|
7
|
+
module Helpers
|
|
8
|
+
include Rack::Utils
|
|
9
|
+
include WillPaginate::ViewHelpers::Base
|
|
10
|
+
|
|
11
|
+
alias_method :h, :escape_html
|
|
12
|
+
|
|
13
|
+
def current_page
|
|
14
|
+
url_path request.path_info.sub('/', '')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def url_path(*path_parts)
|
|
18
|
+
[path_prefix, path_parts].join("/").squeeze('/')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
alias_method :u, :url_path
|
|
22
|
+
|
|
23
|
+
def current_db?
|
|
24
|
+
true if session[:db]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def current_db
|
|
28
|
+
MongoFe::MongoDB.connection.db(session[:db]) if current_db?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def current_db_name
|
|
32
|
+
session[:db] if current_db?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def collection
|
|
36
|
+
current_db.collection(session[:collection]) if current_db? && collection?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def collection?
|
|
40
|
+
true if session[:collection]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def link_to(name, location, alternative = false)
|
|
44
|
+
if alternative && alternative[:condition]
|
|
45
|
+
"<a href=#{alternative[:location]}>#{alternative[:name]}</a>"
|
|
46
|
+
else
|
|
47
|
+
"<a href=#{location}>#{name}</a>"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# prettifying a JSON structure
|
|
52
|
+
def pretty_json(json)
|
|
53
|
+
JSON.pretty_generate(json)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# truncate a string to max characters and append '...' at the end
|
|
57
|
+
def truncate(str, max=0)
|
|
58
|
+
return '' if str.blank?
|
|
59
|
+
|
|
60
|
+
if str.length <= 1
|
|
61
|
+
t_string = str
|
|
62
|
+
else
|
|
63
|
+
t_string = str[0..[str.length, max].min]
|
|
64
|
+
t_string = str.length > t_string.length ? "#{t_string}..." : t_string
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
t_string
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# poor man flash solution
|
|
71
|
+
def flash
|
|
72
|
+
session[:flash] = Hashie::Mash.new if session[:flash].nil?
|
|
73
|
+
session[:flash]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
PLACEHOLDER_SORT = "ex. name:ASC, age:DESC"
|
|
77
|
+
PLACEHOLDER_QUERY_STRING = 'ex. {"name":"foo"}'
|
|
78
|
+
PLACEHOLDER_SHOW = "ex. name, age"
|
|
79
|
+
|
|
80
|
+
# check if there is a query in the session and return its elements as an openstruct object
|
|
81
|
+
def query
|
|
82
|
+
if (q = session[:query])
|
|
83
|
+
OpenStruct.new(:string => q.first.empty? ? '' : q.first.to_json,
|
|
84
|
+
:show => q[1].empty? ? '' : q[1],
|
|
85
|
+
:sort => q.last.empty? ? '' : q.last)
|
|
86
|
+
else
|
|
87
|
+
OpenStruct.new(:string => PLACEHOLDER_QUERY_STRING, :show => PLACEHOLDER_SHOW, :sort => PLACEHOLDER_SORT)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# stolen from http://github.com/cschneid/irclogger/blob/master/lib/partials.rb
|
|
92
|
+
# and made a lot more robust by me: https://gist.github.com/119874.
|
|
93
|
+
# Another me, not me :)
|
|
94
|
+
def partial(template, *args)
|
|
95
|
+
template_array = template.to_s.split('/')
|
|
96
|
+
template = template_array[0..-2].join('/') + "/_#{template_array[-1]}"
|
|
97
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
98
|
+
options.merge!(:layout => false)
|
|
99
|
+
locals = options[:locals] || {}
|
|
100
|
+
|
|
101
|
+
if (collection = options.delete(:collection))
|
|
102
|
+
collection.inject([]) do |buffer, member|
|
|
103
|
+
buffer << haml(:"#{template}",
|
|
104
|
+
options.merge(:layout => false,
|
|
105
|
+
:locals => {template_array[-1].to_sym => member}.merge(locals)))
|
|
106
|
+
end.join("\n")
|
|
107
|
+
else
|
|
108
|
+
haml(:"#{template}", options)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# generate a simple random string
|
|
113
|
+
def random_string(len)
|
|
114
|
+
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
|
115
|
+
str = ""
|
|
116
|
+
1.upto(len) { |i| str << chars[rand(chars.size-1)] }
|
|
117
|
+
str
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
MEGABYTE = 1024.0 * 1024.0
|
|
122
|
+
|
|
123
|
+
# convert Bytes to MegaBytes
|
|
124
|
+
def bytes_to_mb bytes=0
|
|
125
|
+
bytes / MEGABYTE
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|