redis-browser 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb5c55541ef0598f88bd75115276f396a8dc6015
4
- data.tar.gz: 8c87fcd43152e51de0966a69a6ad384d6c8eedb4
3
+ metadata.gz: 37d0ff56203919cb9c9410c192224e8f2cad3ab6
4
+ data.tar.gz: 5f47d5d2485446e8a6567c29bfbd57097ea48030
5
5
  SHA512:
6
- metadata.gz: 95348fcb6e2cb9ca61c334e662f8d77f5259e54d0817fafd5e28382c8b888a5e5a6964c77e3610cdbad43626af831df28f0ab6f600c345d55ba52246f3363a94
7
- data.tar.gz: c3b2cb623f3cb6d9edabcb032af665dd0c7da8de9a511d8407f1b2b81c5487d1cad39cfaed7c23a4976f64d98b59136aea56c58f83e8b5d079dd443eff41d61f
6
+ metadata.gz: 7278bff64d5fdba0cc39611901501745a78dac6e801ccc722a52f425c6074384acf052b544d1f1a5db78e7e231bf590093b626e446a3604dba94ea0c881c0238
7
+ data.tar.gz: 6b1a36d1da3440e536d988a03b5281362b9899ae3f68d4d5fe21864f52b5bc1f3cace4c9dfa5aa91f75d08ed5ed0d9d3e47c470876f357c78694eb0d6ea4edf9
@@ -1,22 +1,20 @@
1
- Copyright (c) 2013 Tymon Tobolski
1
+ The MIT License (MIT)
2
2
 
3
- MIT License
3
+ Copyright (c) 2013-2014 Monterail.com LLC
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
12
11
 
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
15
14
 
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  * List pagination
8
8
  * Pretty print json values
9
9
  * Search keys
10
-
10
+ * Can be mounted to Rails applications as engine
11
11
 
12
12
  ## Installation
13
13
 
@@ -17,10 +17,26 @@ $ gem install redis-browser
17
17
 
18
18
  ## Usage
19
19
 
20
+ ### Standalone
21
+
20
22
  ```bash
21
23
  $ redis-browser
22
24
  ```
23
25
 
26
+ ### As engine
27
+
28
+ Add to gemfile
29
+
30
+ ```ruby
31
+ gem 'redis-browser'
32
+ ```
33
+
34
+ And to routes.rb
35
+
36
+ ```ruby
37
+ mount RedisBrowser::Web => '/redis-browser'
38
+ ```
39
+
24
40
  ## Screenshots
25
41
 
26
42
  ![Browse keys](https://dl.dropboxusercontent.com/u/70986/redis-browser/2.png)
@@ -4,6 +4,6 @@ $:.unshift File.expand_path('../../lib', File.symlink?(__FILE__) ? File.readlink
4
4
 
5
5
  require 'rubygems' unless Object.const_defined?(:Gem)
6
6
 
7
- require "redis-browser/app"
7
+ require "redis-browser"
8
8
 
9
- App.run! :port => 4567
9
+ RedisBrowser::Web.run! :port => 4569
@@ -0,0 +1,10 @@
1
+ require 'sinatra/base'
2
+ require 'multi_json'
3
+ require 'sinatra/json'
4
+ require 'slim'
5
+ require 'coffee-script'
6
+ require 'redis'
7
+ require 'redis-browser/version'
8
+ require 'redis-browser/browser'
9
+ require 'redis-browser/web'
10
+
@@ -0,0 +1,153 @@
1
+ module RedisBrowser
2
+ class Browser
3
+ def initialize(conn = nil, db = 0)
4
+ @conn = conn
5
+ @db = db
6
+ end
7
+
8
+ def split_key(key)
9
+ if key =~ /^(.+?)(:+|\/+|\.+).+$/
10
+ [$1, $2]
11
+ else
12
+ [key, nil]
13
+ end
14
+ end
15
+
16
+ def keys(namespace = nil)
17
+ if namespace.to_s.strip.empty?
18
+ pattern = "*"
19
+ namespace = ""
20
+ else
21
+ pattern = namespace + "*"
22
+ end
23
+
24
+ redis.keys(pattern).inject({}) do |acc, key|
25
+ key.slice!(namespace) if namespace
26
+
27
+ ns, sep = split_key(key)
28
+
29
+ unless ns.strip.empty?
30
+ acc[ns] ||= {
31
+ :name => ns,
32
+ :full => namespace + ns + sep.to_s,
33
+ :count => 0
34
+ }
35
+ acc[ns][:count] += 1
36
+ end
37
+
38
+ acc
39
+ end.values.sort_by {|e| e[:name] }
40
+ end
41
+
42
+ def item_type(e)
43
+ begin
44
+ ["json", MultiJson.decode(e)]
45
+ rescue MultiJson::LoadError => ex
46
+ ["string", e]
47
+ end
48
+ end
49
+
50
+ def get_list(key, opts = {})
51
+ start = opts[:start] ? opts[:start].to_i : 0
52
+ stop = opts[:stop] ? opts[:stop].to_i : 99
53
+
54
+ length = redis.llen(key)
55
+ values = redis.lrange(key, start, stop).map.with_index do |e, i|
56
+ type, value = item_type(e)
57
+ {:type => type, :value => value, :index => start + i}
58
+ end
59
+
60
+ {:length => length, :values => values}
61
+ end
62
+
63
+ def get_set(key)
64
+ values = redis.smembers(key).map do |e|
65
+ type, value = item_type(e)
66
+ {:type => type, :value => value}
67
+ end
68
+
69
+ {:values => values }
70
+ end
71
+
72
+ def get_zset(key)
73
+ values = redis.zrange(key, 0, -1, :withscores => true).map do |e, score|
74
+ type, value = item_type(e)
75
+ {:type => type, :value => value, :score => score}
76
+ end
77
+
78
+ {:values => values }
79
+ end
80
+
81
+ def get_hash(key)
82
+ value = Hash[redis.hgetall(key).map do |k,v|
83
+ type, value = item_type(v)
84
+ [k, {:type => type, :value => value}]
85
+ end]
86
+
87
+ {:value => value}
88
+ end
89
+
90
+ def get_keys(key)
91
+ key << "*" unless key.end_with?("*")
92
+
93
+ values = redis.keys(key).map do |k|
94
+ {:name => k, :full => k}
95
+ end
96
+
97
+ {:values => values}
98
+ end
99
+
100
+ def delete(pattern)
101
+ redis.del(redis.keys(pattern))
102
+ end
103
+
104
+ def get(key, opts = {})
105
+ type = redis.type(key)
106
+ data = case type
107
+ when "string"
108
+ type, value = item_type(redis.get(key))
109
+ {:value => value, :type => type}
110
+ when "list"
111
+ get_list(key, opts)
112
+ when "set"
113
+ get_set(key)
114
+ when "zset"
115
+ get_zset(key)
116
+ when "hash"
117
+ get_hash(key)
118
+ else
119
+ get_keys(key)
120
+ end
121
+
122
+ {
123
+ :full => key,
124
+ :type => type
125
+ }.merge(data)
126
+ end
127
+
128
+ def ping
129
+ redis.ping == "PONG"
130
+ {:ok => 1}
131
+ rescue => ex
132
+ {:error => ex.message}
133
+ end
134
+
135
+ def redis
136
+ @redis ||= begin
137
+ conn = @conn || "127.0.0.1:6379"
138
+ db = @db || 0
139
+
140
+ opts = if conn.start_with?("/")
141
+ {:path => conn}
142
+ else
143
+ host, port = conn.split(":", 2)
144
+ {:host => host, :port => port}
145
+ end
146
+
147
+ r = Redis.new(opts)
148
+ r.select(db)
149
+ r
150
+ end
151
+ end
152
+ end
153
+ end
@@ -22,19 +22,19 @@ app.factory 'API', ['$http', ($http) ->
22
22
  (connection, database) ->
23
23
  ps = {connection: connection, database: database}
24
24
  {
25
- ping: () -> $http.get("/ping.json", {
25
+ ping: () -> $http.get("#{jsEnv.root_path}ping.json", {
26
26
  params: ps
27
27
  }).then (e) -> e.data,
28
28
 
29
- keys: (namespace) -> $http.get("/keys.json", {
29
+ keys: (namespace) -> $http.get("#{jsEnv.root_path}keys.json", {
30
30
  params: angular.extend({}, ps, {namespace: namespace})
31
31
  }).then (e) -> e.data,
32
32
 
33
- get: (params) -> $http.get("/key.json", {
33
+ get: (params) -> $http.get("#{jsEnv.root_path}key.json", {
34
34
  params: angular.extend({}, ps, params)
35
35
  }).then (e) -> e.data
36
36
 
37
- delete: (params) -> $http.delete("/key.json", {
37
+ delete: (params) -> $http.delete("#{jsEnv.root_path}key.json", {
38
38
  params: angular.extend({}, ps, params)
39
39
  })
40
40
  }
@@ -3,13 +3,16 @@ html ng-app="browser"
3
3
  head
4
4
  title Redis Browser
5
5
 
6
- script type="text/javascript" src="/js/angular.min.js"
7
- script type="text/javascript" src="/js/ui-bootstrap-tpls-0.2.0.min.js"
8
- script type="text/javascript" src="/js/localStorageModule.js"
9
- script type="text/javascript" src="/js/app.js"
6
+ script type="text/javascript" src="#{root_path}js/angular.min.js"
7
+ script type="text/javascript" src="#{root_path}js/ui-bootstrap-tpls-0.2.0.min.js"
8
+ script type="text/javascript" src="#{root_path}js/localStorageModule.js"
9
+ script type="text/javascript" src="#{root_path}js/app.js"
10
10
 
11
- link rel="stylesheet" href="/css/bootstrap.min.css"
12
- link rel="stylesheet" href="/css/app.css"
11
+ link rel="stylesheet" href="#{root_path}css/bootstrap.min.css"
12
+ link rel="stylesheet" href="#{root_path}css/app.css"
13
+
14
+ script type="text/javascript"
15
+ == js_env
13
16
 
14
17
  script type="text/ng-template" id="nav-tree-item.html"
15
18
  span ng-show="key.count > 1"
@@ -1,3 +1,3 @@
1
1
  module RedisBrowser
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,61 @@
1
+ module RedisBrowser
2
+ module WebHelpers
3
+ def root_path
4
+ "#{env['SCRIPT_NAME']}/"
5
+ end
6
+
7
+ def js_env
8
+ jsEnv = {
9
+ root_path: "#{root_path}"
10
+ }
11
+
12
+ "jsEnv = #{MultiJson.dump(jsEnv)};"
13
+ end
14
+ end
15
+
16
+ class CoffeeHandler < Sinatra::Base
17
+ set :views, File.dirname(__FILE__) + '/templates/coffee'
18
+
19
+ get "/js/app.js" do
20
+ coffee :app
21
+ end
22
+ end
23
+
24
+ class Web < Sinatra::Base
25
+ helpers Sinatra::JSON, WebHelpers
26
+ use CoffeeHandler
27
+
28
+ set :public_dir, File.dirname(__FILE__) + '/public'
29
+ set :views, File.dirname(__FILE__) + '/templates'
30
+
31
+ get '/' do
32
+ slim :index
33
+ end
34
+
35
+ get '/ping.json' do
36
+ json browser.ping
37
+ end
38
+
39
+ get '/keys.json' do
40
+ json browser.keys(params[:namespace])
41
+ end
42
+
43
+ get '/key.json' do
44
+ json browser.get(params[:key], params)
45
+ end
46
+
47
+ delete '/key.json' do
48
+ browser.delete(params[:key])
49
+ json :ok => true
50
+ end
51
+
52
+ def browser
53
+ connection = if ENV['REDIS_URL']
54
+ ENV['REDIS_URL'].sub(/\Aredis:\/\//, '')
55
+ else
56
+ params[:connection]
57
+ end
58
+ @browser ||= Browser.new(connection, params[:database])
59
+ end
60
+ end
61
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-browser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tymon Tobolski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-02 00:00:00.000000000 Z
11
+ date: 2014-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -150,7 +150,8 @@ files:
150
150
  - README.md
151
151
  - Rakefile
152
152
  - bin/redis-browser
153
- - lib/redis-browser/app.rb
153
+ - lib/redis-browser.rb
154
+ - lib/redis-browser/browser.rb
154
155
  - lib/redis-browser/public/css/app.css
155
156
  - lib/redis-browser/public/css/bootstrap.min.css
156
157
  - lib/redis-browser/public/img/glyphicons-halflings-white.png
@@ -161,6 +162,7 @@ files:
161
162
  - lib/redis-browser/templates/coffee/app.coffee
162
163
  - lib/redis-browser/templates/index.slim
163
164
  - lib/redis-browser/version.rb
165
+ - lib/redis-browser/web.rb
164
166
  - redis-browser.gemspec
165
167
  homepage: http://github.com/teamon/redis-browser
166
168
  licenses:
@@ -182,9 +184,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
184
  version: '0'
183
185
  requirements: []
184
186
  rubyforge_project:
185
- rubygems_version: 2.0.0
187
+ rubygems_version: 2.1.11
186
188
  signing_key:
187
189
  specification_version: 4
188
190
  summary: Redis browser
189
191
  test_files: []
190
- has_rdoc:
@@ -1,201 +0,0 @@
1
- require File.expand_path("../version", __FILE__)
2
- require 'sinatra/base'
3
- require 'multi_json'
4
- require 'sinatra/json'
5
- require 'slim'
6
- require 'coffee-script'
7
- require 'redis'
8
-
9
-
10
- class CoffeeHandler < Sinatra::Base
11
- set :views, File.dirname(__FILE__) + '/templates/coffee'
12
-
13
- get "/js/app.js" do
14
- coffee :app
15
- end
16
- end
17
-
18
- class Browser
19
- def initialize(conn = nil, db = 0)
20
- @conn = conn
21
- @db = db
22
- end
23
-
24
- def split_key(key)
25
- if key =~ /^(.+?)(:+|\/+|\.+).+$/
26
- [$1, $2]
27
- else
28
- [key, nil]
29
- end
30
- end
31
-
32
- def keys(namespace = nil)
33
- if namespace.to_s.strip.empty?
34
- pattern = "*"
35
- namespace = ""
36
- else
37
- pattern = namespace + "*"
38
- end
39
-
40
- redis.keys(pattern).inject({}) do |acc, key|
41
- key.slice!(namespace) if namespace
42
-
43
- ns, sep = split_key(key)
44
-
45
- unless ns.strip.empty?
46
- acc[ns] ||= {
47
- :name => ns,
48
- :full => namespace + ns + sep.to_s,
49
- :count => 0
50
- }
51
- acc[ns][:count] += 1
52
- end
53
-
54
- acc
55
- end.values.sort_by {|e| e[:name] }
56
- end
57
-
58
- def item_type(e)
59
- begin
60
- ["json", MultiJson.decode(e)]
61
- rescue MultiJson::LoadError => ex
62
- ["string", e]
63
- end
64
- end
65
-
66
- def get_list(key, opts = {})
67
- start = opts[:start] ? opts[:start].to_i : 0
68
- stop = opts[:stop] ? opts[:stop].to_i : 99
69
-
70
- length = redis.llen(key)
71
- values = redis.lrange(key, start, stop).map.with_index do |e, i|
72
- type, value = item_type(e)
73
- {:type => type, :value => value, :index => start + i}
74
- end
75
-
76
- {:length => length, :values => values}
77
- end
78
-
79
- def get_set(key)
80
- values = redis.smembers(key).map do |e|
81
- type, value = item_type(e)
82
- {:type => type, :value => value}
83
- end
84
-
85
- {:values => values }
86
- end
87
-
88
- def get_zset(key)
89
- values = redis.zrange(key, 0, -1, :withscores => true).map do |e, score|
90
- type, value = item_type(e)
91
- {:type => type, :value => value, :score => score}
92
- end
93
-
94
- {:values => values }
95
- end
96
-
97
- def get_hash(key)
98
- value = Hash[redis.hgetall(key).map do |k,v|
99
- type, value = item_type(v)
100
- [k, {:type => type, :value => value}]
101
- end]
102
-
103
- {:value => value}
104
- end
105
-
106
- def get_keys(key)
107
- key << "*" unless key.end_with?("*")
108
-
109
- values = redis.keys(key).map do |k|
110
- {:name => k, :full => k}
111
- end
112
-
113
- {:values => values}
114
- end
115
-
116
- def delete(pattern)
117
- redis.del(redis.keys(pattern))
118
- end
119
-
120
- def get(key, opts = {})
121
- type = redis.type(key)
122
- data = case type
123
- when "string"
124
- type, value = item_type(redis.get(key))
125
- {:value => value, :type => type}
126
- when "list"
127
- get_list(key, opts)
128
- when "set"
129
- get_set(key)
130
- when "zset"
131
- get_zset(key)
132
- when "hash"
133
- get_hash(key)
134
- else
135
- get_keys(key)
136
- end
137
-
138
- {
139
- :full => key,
140
- :type => type
141
- }.merge(data)
142
- end
143
-
144
- def ping
145
- redis.ping == "PONG"
146
- {:ok => 1}
147
- rescue => ex
148
- {:error => ex.message}
149
- end
150
-
151
- def redis
152
- @redis ||= begin
153
- conn = @conn || "127.0.0.1:6379"
154
- db = @db || 0
155
-
156
- opts = if conn.start_with?("/")
157
- {:path => conn}
158
- else
159
- host, port = conn.split(":", 2)
160
- {:host => host, :port => port}
161
- end
162
-
163
- r = Redis.new(opts)
164
- r.select(db)
165
- r
166
- end
167
- end
168
- end
169
-
170
- class App < Sinatra::Base
171
- helpers Sinatra::JSON
172
- use CoffeeHandler
173
-
174
- set :public_dir, File.dirname(__FILE__) + '/public'
175
- set :views, File.dirname(__FILE__) + '/templates'
176
-
177
- get '/' do
178
- slim :index
179
- end
180
-
181
- get '/ping.json' do
182
- json browser.ping
183
- end
184
-
185
- get '/keys.json' do
186
- json browser.keys(params[:namespace])
187
- end
188
-
189
- get '/key.json' do
190
- json browser.get(params[:key], params)
191
- end
192
-
193
- delete '/key.json' do
194
- browser.delete(params[:key])
195
- json :ok => true
196
- end
197
-
198
- def browser
199
- @browser ||= Browser.new(params[:connection], params[:database])
200
- end
201
- end