mongo_web 0.0.1 → 0.0.2

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.
@@ -1,7 +1,7 @@
1
- Mongo_Web
1
+ MongoWeb
2
2
  ========
3
3
 
4
- Mongo_Web is the stylish way of inspecting MongoDB databases.
4
+ MongoWeb is the stylish way of inspecting MongoDB databases.
5
5
 
6
6
  Installing
7
7
  ----------
@@ -15,17 +15,29 @@ Starting MongoWeb is simple
15
15
 
16
16
  $ mongo-web
17
17
 
18
- You can also pass it a specific port
18
+ You can also pass it a specific port for the MongoWeb web server
19
19
 
20
20
  $ mongo-web -p 6969
21
+
22
+ You can connect to remote databases as well
23
+
24
+ $ mongo-web [DATABASE CONNECTION STRING] --mongo-username USERNAME --mongo-password PASSWORD
25
+
26
+ Valid connection strings are
27
+
28
+ foo # equivalent to localhost:27017/foo
29
+ localhost/foo # equivalent to localhost:27017/foo
30
+ localhost:27018/foo
21
31
 
22
32
  TODO
23
33
  -----------
24
34
 
25
35
  Support for:
36
+
26
37
  * GridFS
27
38
  * Editing Data
28
- * Ports
29
- * Usernames, passwords
30
39
 
31
- ![Screenshot] (http://img.skitch.com/20100430-jdmu6nxijpbmq5ur72gwayghs7.jpg)
40
+ Screenshot
41
+ -----------------
42
+
43
+ ![Screenshot](http://img.skitch.com/20100430-jdmu6nxijpbmq5ur72gwayghs7.jpg)
@@ -9,4 +9,9 @@ rescue LoadError
9
9
  end
10
10
  require 'server'
11
11
 
12
- Vegas::Runner.new(MongoWeb::Server, 'mongo-web')
12
+ Vegas::Runner.new(
13
+ MongoWeb::Server,
14
+ 'mongo-web',
15
+ { :before_run => MongoWeb::Server::MONGO_CONNECTION_SETUP },
16
+ &MongoWeb::Server::OPTIONS_SETUP
17
+ )
@@ -2,17 +2,57 @@ require 'rubygems'
2
2
  require 'sinatra'
3
3
  require 'haml'
4
4
  require 'mongo'
5
+ require 'yajl'
5
6
 
6
7
  module MongoWeb
7
8
  class Server < Sinatra::Base
9
+ DEFAULT_MONGO_HOST = "localhost"
10
+ DEFAULT_MONGO_PORT = 27017
11
+ MONGO_CONNECTION_SETUP = lambda { |r| r.app.set_mongo_connection_from_args(r.args.first) }
12
+ OPTIONS_SETUP = proc do |runner, opts, app|
13
+ opts.on('--mongo-username USERNAME', 'username for authentication against MongoDB database') do |mongo_username|
14
+ app.set(:mongo_username, mongo_username)
15
+ end
16
+
17
+ opts.on('--mongo-password PASSWORD', 'password for authentication against MongoDB database') do |mongo_password|
18
+ app.set(:mongo_password, mongo_password)
19
+ end
20
+
21
+ opts.banner = "Usage: #{$0 || app_name} [options] [database_connection_string]"
22
+ end
23
+
8
24
  dir = File.dirname(File.expand_path(__FILE__))
9
25
  set :views, "#{dir}/server/views"
26
+ set :public, "public"
10
27
  set :static, true
11
28
  set :haml, { :format => :html5 }
12
29
 
30
+ set :mongo, nil
31
+ set :mongo_username, nil
32
+ set :mongo_password, nil
33
+ set :mongo_database_name, nil
34
+ set :mongo_admin, false
35
+
36
+ def self.set_mongo_connection_from_args(connection_string)
37
+ host, port, database_name = connection_string.to_s.scan(/^(?:([^:]+?)(?::([^\/]+?))?\/)?(.+)$/).first
38
+ effective_host = host || DEFAULT_MONGO_HOST
39
+ effective_port = port || DEFAULT_MONGO_PORT
40
+
41
+ connection = Mongo::Connection.new(effective_host, effective_port)
42
+ set(:mongo, connection)
43
+
44
+ if database_name && self.mongo_username && self.mongo_password
45
+ database = mongo.db(database_name)
46
+ database.authenticate(self.mongo_username, self.mongo_password)
47
+ set(:mongo_database_name, database_name)
48
+ else
49
+ set(:mongo_admin, true)
50
+ end
51
+ end
52
+
13
53
  helpers do
14
54
  def mongo
15
- @mongo ||= Mongo::Connection.new
55
+ settings.mongo
16
56
  end
17
57
 
18
58
  def databases
@@ -20,30 +60,108 @@ module MongoWeb
20
60
  end
21
61
 
22
62
  def collections(database_name)
23
- mongo.db(database_name).collections
63
+ collections = mongo.db(database_name).collections
64
+ unless settings.mongo_admin
65
+ collections.reject { |collection| collection.name.match(/^system\./) }
66
+ else
67
+ collections
68
+ end
24
69
  end
25
70
 
26
71
  def documents(database_name, collection_name)
27
72
  mongo.db(database_name)[collection_name].find()
28
- end
73
+ end
74
+
75
+ def document(database_name, collection_name, id)
76
+ mongo.db(database_name)[collection_name].find_one({ '_id' => BSON::ObjectID.from_string(id) })
77
+ end
78
+
79
+ def breadcrumbs
80
+ bc = []
81
+
82
+ if @database_name && @collection && @document
83
+ bc << %Q{<a href="/overview">databases</a>}
84
+ bc << %Q{<a href="/database/#{@database_name}">#{@database_name}</a>}
85
+ bc << %Q{<a href="/database/#{@database_name}/#{@collection}">#{@collection}</a>}
86
+ bc << @document_id
87
+ elsif @database_name && @collection
88
+ bc << %Q{<a href="/overview">databases</a>}
89
+ bc << %Q{<a href="/database/#{@database_name}">#{@database_name}</a>}
90
+ bc << @collection
91
+ elsif @database_name
92
+ bc << %Q{<a href="/overview">databases</a>}
93
+ bc << @database_name
94
+ end
95
+
96
+ bc
97
+ end
98
+
99
+ def pretty_value(value)
100
+ case value
101
+ when String, Fixnum, BSON::ObjectID
102
+ value.to_s
103
+ when Hash, Array
104
+ "<pre>#{Yajl::Encoder.encode(value, :pretty => true)}</pre>"
105
+ else
106
+ value.inspect
107
+ end
108
+ end
109
+
110
+ def truncate(text, length = 30, omission = '...')
111
+ return unless text
112
+ return text if text.length < length
113
+
114
+ out_text_length = (length / 2).floor
115
+ text.slice(0, out_text_length) + omission + text.slice(-out_text_length, out_text_length)
116
+ end
117
+
118
+ def hash_without(hash, *keys)
119
+ hash.inject({}) do |out, pair|
120
+ key, value = pair
121
+ next out if keys.include?(key)
122
+
123
+ out[key] = value
124
+ out
125
+ end
126
+ end
29
127
  end
30
128
 
31
129
  get '/' do
32
- redirect '/overview'
130
+ if settings.mongo_admin
131
+ redirect '/overview'
132
+ else
133
+ redirect "/database/#{settings.mongo_database_name}"
134
+ end
33
135
  end
34
136
 
35
137
  get '/overview' do
138
+ unless settings.mongo_admin
139
+ redirect "/database/#{settings.mongo_database_name}"
140
+ end
141
+
36
142
  haml :overview
37
143
  end
38
144
 
39
- get '/database/:name' do
145
+ get '/database/:database_name' do |database_name|
146
+ @database_name = database_name
40
147
  haml :database
41
148
  end
42
149
 
43
- get '/database/:name/:collection' do
150
+ get '/database/:database_name/:collection' do |database_name, collection|
151
+ @database_name = database_name
152
+ @collection = collection
44
153
  haml :collection
45
154
  end
46
155
 
156
+ get '/database/:database_name/:collection/:id' do |database_name, collection, id|
157
+ @database_name = database_name
158
+ @collection = collection
159
+ @document_id = id
160
+
161
+ @document = document(database_name, collection, id)
162
+ haml :document
163
+ end
164
+
47
165
  get '/stylesheet.css' do
48
166
  content_type 'text/css', :charset => 'utf-8'
49
167
  sass :stylesheet
@@ -1,15 +1,9 @@
1
- -name = params[:name]
2
- -collection = params[:collection]
3
-
4
- %h2 #{name} >> #{collection} >> documents
5
-
6
1
  %table
7
2
  %tr
8
- %th
9
- %h3 Id
10
- %th
11
- %h3 Values
12
- -for document in documents(name, collection)
3
+ %th ID
4
+ %th Values
5
+ -for document in documents(@database_name, @collection)
13
6
  %tr
14
- %td= document['_id']
15
- %td= document.inspect
7
+ %td{ :class => 'monospace' }
8
+ %a{ :href => "/database/#{@database_name}/#{@collection}/#{document['_id']}" }= document['_id']
9
+ %td{ :class => 'monospace' }= truncate(hash_without(document, '_id').inspect, 80)
@@ -1,15 +1,9 @@
1
- -name = params[:name]
2
-
3
- %h2 #{name} >> collections
4
-
5
1
  %table
6
2
  %tr
7
- %th
8
- %h3 Name
9
- %th
10
- %h3 Size
11
- -for collection in collections(name)
3
+ %th Name
4
+ %th Size
5
+ -for collection in collections(@database_name)
12
6
  %tr
13
7
  %td
14
- %a{:href => "#{name}/#{collection.name}"}= collection.name
8
+ %a{:href => "#{@database_name}/#{collection.name}"}= collection.name
15
9
  %td= collection.size
@@ -0,0 +1,8 @@
1
+ %table
2
+ %tr
3
+ %th Key
4
+ %th Value
5
+ -@document.each do |key, value|
6
+ %tr
7
+ %td{ :class => 'key' }= key
8
+ %td{ :class => 'value' }= pretty_value(value)
@@ -4,8 +4,16 @@
4
4
  %title MongoWeb
5
5
  %link{ :href => '/stylesheet.css', :media => 'screen', :rel => 'stylesheet', :type => 'text/css'}
6
6
  %body
7
- #wrapper
8
- %h1 MongoWeb
9
- #site= yield
10
- %a{ :href => 'http://mongodb.org' }
11
- %img{ :src => 'http://api.mongodb.org/wiki/current/attachments/132305/1605648.png' }
7
+ #container
8
+ #header
9
+ %h1 MongoWeb
10
+
11
+ -unless breadcrumbs.empty?
12
+ %ul
13
+ -for breadcrumb in breadcrumbs
14
+ %li= breadcrumb
15
+
16
+ #content= yield
17
+
18
+ #footer
19
+ %img{ :src => '/images/PoweredMongoDBblue50.png' }
@@ -1,6 +1,7 @@
1
- %h2 Databases
2
-
3
1
  %table
2
+ %tr
3
+ %th= "database name"
4
+
4
5
  -for name in databases
5
6
  %tr
6
7
  %td
@@ -1,49 +1,77 @@
1
- !dark_brown = #402817
2
- !light_brown = #F6F4CD
3
- !light_gray = #FDFCF7
1
+ body
2
+ background-color= #CCC
3
+ font-family= Helvetica, Arial, sans-serif
4
4
 
5
- =plain_anchor
6
- a
7
- text-decoration: none
8
- color: black
9
- font:
10
- size: 1.2em
11
- weight: 600
12
- a:hover
13
- text-decoration: underline
5
+ a
6
+ color= #000
14
7
 
15
- html
16
- background-color= !light_brown
17
-
18
- h2
19
- margin: 0px
20
- font-size: 1.3em
8
+ #container
9
+ background-color= #FFF
10
+ margin= 40px auto 0
11
+ width= 960px
12
+ -webkit-box-shadow= 0 0 5px rgba(0, 0, 0, .2)
13
+ -moz-box-shadow= 0 0 5px rgba(0, 0, 0, .2)
14
+ -webkit-border-radius= 5px
15
+ -moz-border-radius= 5px
21
16
 
22
- h3
23
- margin:
24
- top: 15px
25
- bottom: 5px
26
-
27
- #wrapper
28
- width: 800px
29
- margin:
30
- right: auto
31
- left: auto
32
- #site
33
- -webkit-border-radius: 15px
34
- -moz-border-radius: 15px
35
- border: 2px solid
36
- color= !dark_brown
37
- padding: 15px
38
- background-color= !light_gray
17
+ #header
18
+ h1
19
+ font-size= 1.5em
20
+ background-color= #77BED2
21
+ margin= 0
22
+ padding= 7px 0 7px 15px
23
+ -webkit-border-top-left-radius= 5px
24
+ -webkit-border-top-right-radius= 5px
25
+ -moz-border-radius-topleft= 5px
26
+ -moz-border-radius-topright= 5px
27
+
28
+ ul
29
+ border-bottom= 1px solid #CCC
30
+ list-style= none
31
+ padding= 10px 0 10px 15px
32
+ margin= 0
33
+ overflow= auto
34
+
35
+ li
36
+ float= left
37
+ margin-right= 15px
38
+ text-transform= uppercase
39
+
40
+ &:after
41
+ :content '>>'
42
+ :padding-left 15px
43
+
44
+ &:last-child
45
+ :font-weight bold
46
+
47
+ &:after
48
+ :content ''
49
+
50
+ #content
51
+ padding= 5px 15px 15px 15px
52
+
39
53
  table
40
- +plain_anchor
41
- border-collapse: collapse
42
- width: 100%
43
- text-align: left
54
+ border-collapse= collapse
55
+ width= 100%
56
+ text-align= left
57
+
58
+ th
59
+ padding= 10px
60
+ text-transform= uppercase
61
+
44
62
  td
45
- padding: 10px
46
- border: 1px solid black
47
- img
48
- float: right
49
- margin-top: 10px
63
+ padding= 10px
64
+ border= 1px solid black
65
+ vertical-align= top
66
+
67
+ td.monospace
68
+ font-family= monospace
69
+
70
+ td.key
71
+ font-weight= bold
72
+
73
+ #footer
74
+ margin= 0 auto 25px
75
+ padding-top= 10px
76
+ text-align= right
77
+ width= 960px
metadata CHANGED
@@ -5,16 +5,17 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ethan Gunderson
13
+ - Ryan Briones
13
14
  autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-04-30 00:00:00 -05:00
18
+ date: 2010-06-03 00:00:00 -05:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
@@ -57,6 +58,30 @@ dependencies:
57
58
  version: 0.9.2
58
59
  type: :runtime
59
60
  version_requirements: *id003
61
+ - !ruby/object:Gem::Dependency
62
+ name: haml
63
+ prerelease: false
64
+ requirement: &id004 !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ type: :runtime
72
+ version_requirements: *id004
73
+ - !ruby/object:Gem::Dependency
74
+ name: yajl-ruby
75
+ prerelease: false
76
+ requirement: &id005 !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ type: :runtime
84
+ version_requirements: *id005
60
85
  description: " Mongo_Web is a sinatra application for viewing MongoDB databases.\n \n If the code looks a lot like resque_web, that would be because I borrowed heavily from their implementation.\n"
61
86
  email: ethan@ethangunderson.com
62
87
  executables:
@@ -69,6 +94,7 @@ files:
69
94
  - README.markdown
70
95
  - lib/server/views/collection.haml
71
96
  - lib/server/views/database.haml
97
+ - lib/server/views/document.haml
72
98
  - lib/server/views/layout.haml
73
99
  - lib/server/views/overview.haml
74
100
  - lib/server/views/stylesheet.css
@@ -76,6 +102,7 @@ files:
76
102
  - lib/server.rb
77
103
  - bin/mongo-web
78
104
  - spec/mongo_web_spec.rb
105
+ - public/images/PoweredMongoDBblue50.png
79
106
  has_rdoc: true
80
107
  homepage: http://github.com/ethangunderson/mongo_web
81
108
  licenses: []