cassandra-web 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/README.md +31 -4
- data/app.rb +17 -27
- data/app/helpers/async.rb +46 -0
- data/app/helpers/json.rb +82 -13
- data/app/helpers/sse.rb +1 -1
- data/bin/cassandra-web +27 -13
- metadata +47 -32
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MDIxN2VhZDIyOGQwMmQzM2M3ZjUyMjg0ZTMwNDU5MWZhZmM2ODljZg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTAxYjlmNWQ5ZDI2Y2FiZjUyMjdhMGExNzZkYzk4NTEzZTI5N2VhMw==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Njc2ODUzMjc4YzE0NTczYmFmMDQ4MmNhZGRhZmMxZTFiNmNjNzdjZDE2OGQy
|
10
|
+
OTI3ZTlmZTNiOTVjZTAxNWY5NmUwZjc0ZDU2MjI2YTg0ZWEwZmEzODg3YzUz
|
11
|
+
MWY1ZGFiOTNkNDkxMTgxYmQxYWM4NTFiYTRhOGIxMzIxYzRhMWM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
Yjc2MGM5MmExMDNjMzY3ZmM4YWVkMTZjYzI0OTllZDFkNzkyZTRkMmQ5ZWQx
|
14
|
+
NGI3YWE3ZWIxN2M3MjliMDIzZTk4MmM1NGVmMzZkZWJjNzliYTQyMzA2MzJm
|
15
|
+
YTMwZjU4ZDc5ZGRiMjc5Mzc5ZTEwMGJmMDBjM2Q4ZjY1MGYwMDQ=
|
data/README.md
CHANGED
@@ -2,20 +2,47 @@
|
|
2
2
|
|
3
3
|
A web interface to Apache Cassandra with AngularJS and server-sent events.
|
4
4
|
|
5
|
-
##
|
5
|
+
## Installation
|
6
6
|
|
7
7
|
```bash
|
8
|
-
gem install cassandra-web
|
9
|
-
cassandra-web
|
8
|
+
$ gem install cassandra-web
|
10
9
|
```
|
11
10
|
|
12
|
-
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
```bash
|
14
|
+
$ cassandra-web
|
15
|
+
```
|
16
|
+
|
17
|
+
Run `cassandra-web -h` for futher help.
|
18
|
+
|
19
|
+
## How it works
|
20
|
+
|
21
|
+
Cassandra web consists of an HTTP API powered by [Sinatra](https://github.com/sinatra/sinatra) and a thin HTML5/JavaScript frontend powered by [AngularJS](https://angularjs.org/).
|
22
|
+
|
23
|
+
When you run `cassandra-web` script, it starts a [Thin web server](http://code.macournoyer.com/thin/) on a specified address, which defaults to `localhost:3000`. Openning `http://localhost:3000`, or whatever address you've specified in the browser, loads the AngularJS application and it starts interacting with the HTTP API of `cassandra-web`. This api uses the [Ruby Driver](http://datastax.github.io/ruby-driver/) to communicate with an [Apache Cassandra](http://cassandra.apache.org/) cluster.
|
24
|
+
|
25
|
+
When the frontend has fully loaded, [it subscribes to `/events` API endpoint](https://github.com/avalanche123/cassandra-web/blob/master/app/public/js/cassandra.js#L108), and begins receiving [Server Sent Events](http://www.w3.org/TR/2012/WD-eventsource-20120426/). [The API uses an event listener, which is registered with the `Cluster` instance created by the Ruby Driver, to stream events](https://github.com/avalanche123/cassandra-web/blob/master/app/helpers/sse.rb#L43-L56) such as [schema](https://github.com/avalanche123/cassandra-web/blob/master/app/helpers/sse.rb#L29-L39) and [node status](https://github.com/avalanche123/cassandra-web/blob/master/app/helpers/sse.rb#L13-L27) changes to update the user interface without having to refresh the page.
|
26
|
+
|
27
|
+
You can see this feature in action by creating a keyspace using the execute button in the top-right corner of the UI and executing the following statement:
|
28
|
+
|
29
|
+
```cql
|
30
|
+
CREATE KEYSPACE example WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}
|
31
|
+
```
|
32
|
+
|
33
|
+
If the statement executed successfully, you should see a new keyspace show up on the left side of the UI.
|
34
|
+
|
35
|
+
![Alt text](https://raw.githubusercontent.com/avalanche123/cassandra-web/master/animation.gif "Create Keyspace")
|
36
|
+
|
37
|
+
The web server, Thin, used by `cassandra-web` is asynchronous and uses only a single thread to handle requests. This enables efficient handling multiple of long running connections, which is a requirement for streaming and Server Sent Events, but also means that the application cannot perform blocking operations during request handling, since it would hang up all connections for the duration of the blocking operation. `cassandra-web` therefore uses Asynchronous Execution feature of the Ruby Driver to not block on statements execution. [The application executes statements asynchronously, receiving a future from the Ruby Driver](https://github.com/avalanche123/cassandra-web/blob/master/app.rb#L88). [It then registers future completion listeners to send a response (or error) whenever it becomes available](https://github.com/avalanche123/cassandra-web/blob/master/app/helpers/async.rb#L7-L40).
|
13
38
|
|
14
39
|
## Credits
|
15
40
|
|
16
41
|
Cassandra web is possible because of the following awesome technologies (in no particular order):
|
17
42
|
|
18
43
|
* [Apache Cassandra](http://cassandra.apache.org/)
|
44
|
+
* [DataStax Ruby Driver for Apache Cassandra](http://datastax.github.io/ruby-driver/)
|
45
|
+
* [Sinatra](https://github.com/sinatra/sinatra)
|
19
46
|
* [AngularJS](https://angularjs.org/)
|
20
47
|
* [Twitter Bootstrap](http://getbootstrap.com/)
|
21
48
|
* [Thin](http://code.macournoyer.com/thin/)
|
data/app.rb
CHANGED
@@ -43,7 +43,7 @@ class App < Sinatra::Base
|
|
43
43
|
headers 'Connection' => 'keep-alive'
|
44
44
|
|
45
45
|
stream(:keep_open) do |out|
|
46
|
-
|
46
|
+
stream_events(out)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -71,33 +71,21 @@ class App < Sinatra::Base
|
|
71
71
|
post '/execute/?' do
|
72
72
|
content_type 'application/json'
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if params['options']
|
85
|
-
|
86
|
-
options[:consistency] = params['options']['consistency'].to_sym if params['options'].has_key?('consistency') && Cassandra::CONSISTENCIES.include?(params['options']['consistency'].to_sym)
|
87
|
-
end
|
88
|
-
|
89
|
-
status 200
|
90
|
-
json_dump(session.execute(statement, options))
|
91
|
-
rescue Cassandra::Errors::NoHostsAvailable => e
|
92
|
-
status 503
|
93
|
-
json_dump(e)
|
94
|
-
rescue Cassandra::Errors::QueryError => e
|
95
|
-
status 400
|
96
|
-
json_dump(e)
|
97
|
-
rescue => e
|
98
|
-
status 500
|
99
|
-
json_dump(e)
|
74
|
+
statement = params['statement']
|
75
|
+
statement.strip!
|
76
|
+
statement.chomp!(";")
|
77
|
+
|
78
|
+
options = {
|
79
|
+
:consistency => :one,
|
80
|
+
:trace => false
|
81
|
+
}
|
82
|
+
|
83
|
+
if params['options']
|
84
|
+
options[:trace] = !!params['options']['trace'] if params['options'].has_key?('trace')
|
85
|
+
options[:consistency] = params['options']['consistency'].to_sym if params['options'].has_key?('consistency') && Cassandra::CONSISTENCIES.include?(params['options']['consistency'].to_sym)
|
100
86
|
end
|
87
|
+
|
88
|
+
defer(session.execute_async(statement, options))
|
101
89
|
end
|
102
90
|
|
103
91
|
get '*' do
|
@@ -105,8 +93,10 @@ class App < Sinatra::Base
|
|
105
93
|
end
|
106
94
|
end
|
107
95
|
|
96
|
+
require 'app/helpers/async'
|
108
97
|
require 'app/helpers/json'
|
109
98
|
require 'app/helpers/sse'
|
110
99
|
|
100
|
+
App.helpers App::Helpers::Async
|
111
101
|
App.helpers App::Helpers::JSON
|
112
102
|
App.helpers App::Helpers::SSE
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class App
|
4
|
+
module Helpers
|
5
|
+
module Async
|
6
|
+
def defer(future)
|
7
|
+
future.on_success do |result|
|
8
|
+
env["async.callback"].call([
|
9
|
+
200,
|
10
|
+
{
|
11
|
+
'Content-Type' => 'application/json'
|
12
|
+
},
|
13
|
+
[json_dump(result)]
|
14
|
+
])
|
15
|
+
end
|
16
|
+
|
17
|
+
future.on_failure do |error|
|
18
|
+
status = case error
|
19
|
+
when Cassandra::Errors::NoHostsAvailable
|
20
|
+
503
|
21
|
+
when Cassandra::Errors::AuthenticationError
|
22
|
+
401
|
23
|
+
when Cassandra::Errors::UnauthorizedError
|
24
|
+
403
|
25
|
+
when Cassandra::Errors::ExecutionError
|
26
|
+
504
|
27
|
+
when Cassandra::Error
|
28
|
+
400
|
29
|
+
when
|
30
|
+
500
|
31
|
+
end
|
32
|
+
|
33
|
+
env["async.callback"].call([
|
34
|
+
status,
|
35
|
+
{
|
36
|
+
'Content-Type' => 'application/json'
|
37
|
+
},
|
38
|
+
[json_dump(error)]
|
39
|
+
])
|
40
|
+
end
|
41
|
+
|
42
|
+
throw :async
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/app/helpers/json.rb
CHANGED
@@ -17,12 +17,8 @@ class App
|
|
17
17
|
keyspace_hash(object)
|
18
18
|
when ::Cassandra::Result
|
19
19
|
result_hash(object)
|
20
|
-
when ::Cassandra::Errors::NoHostsAvailable
|
21
|
-
no_hosts_available_error_hash(object)
|
22
|
-
when ::Cassandra::Errors::QueryError
|
23
|
-
query_error_hash(object)
|
24
20
|
when ::Exception
|
25
|
-
|
21
|
+
exception_hash(object)
|
26
22
|
when ::Hash
|
27
23
|
hash = ::Hash.new
|
28
24
|
object.each do |key, value|
|
@@ -98,14 +94,14 @@ class App
|
|
98
94
|
def result_hash(result)
|
99
95
|
{
|
100
96
|
:rows => result.map(&method(:object_hash)),
|
101
|
-
:columns => columns_hash(result
|
97
|
+
:columns => columns_hash(result),
|
102
98
|
:info => execution_info_hash(result.execution_info),
|
103
99
|
}
|
104
100
|
end
|
105
101
|
|
106
|
-
def columns_hash(
|
107
|
-
return [] if
|
108
|
-
|
102
|
+
def columns_hash(rows)
|
103
|
+
return [] if rows.empty?
|
104
|
+
rows.first.keys
|
109
105
|
end
|
110
106
|
|
111
107
|
def execution_info_hash(execution_info)
|
@@ -159,19 +155,92 @@ class App
|
|
159
155
|
end
|
160
156
|
|
161
157
|
def error_hash(error)
|
158
|
+
case error
|
159
|
+
when ::Cassandra::Errors::NoHostsAvailable
|
160
|
+
no_hosts_available_error_hash(error)
|
161
|
+
when ::Cassandra::Errors::ReadTimeoutError
|
162
|
+
read_timeout_error_hash(error)
|
163
|
+
when ::Cassandra::Errors::WriteTimeoutError
|
164
|
+
write_timeout_error_hash(error)
|
165
|
+
when ::Cassandra::Errors::UnavailableError
|
166
|
+
unavailable_error_hash(error)
|
167
|
+
when ::Cassandra::Errors::UnpreparedError
|
168
|
+
unprepared_error_hash(error)
|
169
|
+
when ::Cassandra::Errors::AlreadyExistsError
|
170
|
+
already_exists_error_hash(error)
|
171
|
+
when ::Cassandra::Errors::ExecutionError, ::Cassandra::Errors::ValidationError
|
172
|
+
execution_error_hash(error)
|
173
|
+
else
|
174
|
+
exception_hash(error)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def exception_hash(error)
|
162
179
|
{
|
163
180
|
:class => error.class.name,
|
164
181
|
:message => error.message,
|
165
|
-
:trace
|
182
|
+
:trace => error.backtrace
|
166
183
|
}
|
167
184
|
end
|
168
185
|
|
169
|
-
def
|
170
|
-
|
186
|
+
def execution_error_hash(error)
|
187
|
+
hash = exception_hash(error)
|
188
|
+
hash[:statement] = statement_hash(error.statement)
|
189
|
+
hash
|
190
|
+
end
|
191
|
+
|
192
|
+
def already_exists_error_hash(error)
|
193
|
+
hash = execution_error_hash(error)
|
194
|
+
hash[:keyspace] = error.keyspace
|
195
|
+
hash[:table] = error.table
|
196
|
+
hash
|
197
|
+
end
|
198
|
+
|
199
|
+
def unprepared_error_hash(error)
|
200
|
+
hash = execution_error_hash(error)
|
201
|
+
hash[:id] = error.id
|
202
|
+
hash
|
203
|
+
end
|
204
|
+
|
205
|
+
def read_timeout_error_hash(error)
|
206
|
+
hash = execution_error_hash(error)
|
207
|
+
hash[:retrieved] = error.retrieved?
|
208
|
+
hash[:consistency] = error.consistency
|
209
|
+
hash[:required] = error.required
|
210
|
+
hash[:received] = error.received
|
211
|
+
hash
|
212
|
+
end
|
213
|
+
|
214
|
+
def write_timeout_error_hash(error)
|
215
|
+
hash = execution_error_hash(error)
|
216
|
+
hash[:type] = error.type
|
217
|
+
hash[:consistency] = error.consistency
|
218
|
+
hash[:required] = error.required
|
219
|
+
hash[:received] = error.received
|
220
|
+
hash
|
221
|
+
end
|
222
|
+
|
223
|
+
def unavailable_error_hash(error)
|
224
|
+
hash = execution_error_hash(error)
|
225
|
+
hash[:consistency] = error.consistency
|
226
|
+
hash[:required] = error.required
|
227
|
+
hash[:alive] = error.alive
|
228
|
+
hash
|
171
229
|
end
|
172
230
|
|
173
231
|
def no_hosts_available_error_hash(error)
|
174
|
-
|
232
|
+
hash = exception_hash(error)
|
233
|
+
errors = []
|
234
|
+
|
235
|
+
error.errors.each do |host, e|
|
236
|
+
errors << {
|
237
|
+
:host => host_hash(host),
|
238
|
+
:error => error_hash(e)
|
239
|
+
}
|
240
|
+
end
|
241
|
+
|
242
|
+
hash[:errors] = errors
|
243
|
+
hash
|
175
244
|
end
|
176
245
|
end
|
177
246
|
end
|
data/app/helpers/sse.rb
CHANGED
data/bin/cassandra-web
CHANGED
@@ -21,16 +21,20 @@ class CLI
|
|
21
21
|
@parser = OptionParser.new
|
22
22
|
@options = {
|
23
23
|
:bind => '0.0.0.0:3000',
|
24
|
-
:log_level => '
|
24
|
+
:log_level => 'info'
|
25
25
|
}
|
26
26
|
|
27
|
-
option(:bind, '-B', '--bind BIND', String, 'ip:port or path for cassandra web to bind on')
|
28
|
-
option(:hosts, '-H', '--hosts HOSTS', String, 'coma-separated list of cassandra hosts')
|
29
|
-
option(:port, '-P', '--port PORT', Integer, 'integer port that cassandra is running on')
|
27
|
+
option(:bind, '-B', '--bind BIND', String, 'ip:port or path for cassandra web to bind on (default: 0.0.0.0:3000)')
|
28
|
+
option(:hosts, '-H', '--hosts HOSTS', String, 'coma-separated list of cassandra hosts (default: 127.0.0.1)')
|
29
|
+
option(:port, '-P', '--port PORT', Integer, 'integer port that cassandra is running on (default: 9042)')
|
30
|
+
option(:log_level, '-L', '--log-level LEVEL', String, 'log level (default: info)')
|
30
31
|
option(:username, '-u', '--username USER', String, 'username to use when connecting to cassandra')
|
31
32
|
option(:password, '-p', '--password PASS', String, 'password to use when connecting to cassandra')
|
32
33
|
option(:compression, '-C', '--compression NAME', String, 'compression algorithm to use (lz4 or snappy)')
|
33
|
-
option(:
|
34
|
+
option(:server_cert, '--server-cert PATH', String, 'server ceritificate pathname')
|
35
|
+
option(:client_cert, '--client-cert PATH', String, 'client ceritificate pathname')
|
36
|
+
option(:private_key, '--private-key PATH', String, 'path to private key')
|
37
|
+
option(:passphrase, '--passphrase SECRET', String, 'passphrase for the private key')
|
34
38
|
|
35
39
|
@parser.on('-h', '--help', 'Show help') { show_help }
|
36
40
|
end
|
@@ -45,14 +49,17 @@ class CLI
|
|
45
49
|
|
46
50
|
@options.each do |name, value|
|
47
51
|
value = case name
|
48
|
-
when :
|
49
|
-
when :
|
50
|
-
|
52
|
+
when :port, :username, :password # skip as is
|
53
|
+
when :hosts
|
54
|
+
value.split(',').map!(&:strip)
|
55
|
+
when :compression
|
56
|
+
value.downcase.to_sym
|
51
57
|
when :log_level
|
52
|
-
name
|
53
|
-
|
54
|
-
|
55
|
-
|
58
|
+
name = :logger
|
59
|
+
|
60
|
+
logger = Logger.new(@out)
|
61
|
+
logger.level = Logger.const_get(value.upcase.to_sym)
|
62
|
+
logger
|
56
63
|
else
|
57
64
|
next
|
58
65
|
end
|
@@ -60,7 +67,14 @@ class CLI
|
|
60
67
|
options[name] = value
|
61
68
|
end
|
62
69
|
|
63
|
-
|
70
|
+
hosts = Array(options[:hosts])
|
71
|
+
hosts << '127.0.0.1' if hosts.empty?
|
72
|
+
|
73
|
+
options[:load_balancing_policy] = ::Cassandra::LoadBalancing::Policies::WhiteList.new(hosts, ::Cassandra::LoadBalancing::Policies::RoundRobin.new)
|
74
|
+
options[:compression] = :lz4
|
75
|
+
options[:page_size] = nil
|
76
|
+
|
77
|
+
cluster = ::Cassandra.cluster(options)
|
64
78
|
|
65
79
|
App.set(:cluster, cluster)
|
66
80
|
App.set(:session, cluster.connect)
|
metadata
CHANGED
@@ -1,113 +1,127 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cassandra-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bulat Shakirzyanov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
+
name: cassandra-driver
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
14
21
|
prerelease: false
|
15
22
|
version_requirements: !ruby/object:Gem::Requirement
|
16
23
|
requirements:
|
17
24
|
- - ~>
|
18
25
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
20
|
-
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thin
|
21
29
|
requirement: !ruby/object:Gem::Requirement
|
22
30
|
requirements:
|
23
31
|
- - ~>
|
24
32
|
- !ruby/object:Gem::Version
|
25
|
-
version: 1.
|
26
|
-
|
27
|
-
- !ruby/object:Gem::Dependency
|
33
|
+
version: '1.6'
|
34
|
+
type: :runtime
|
28
35
|
prerelease: false
|
29
36
|
version_requirements: !ruby/object:Gem::Requirement
|
30
37
|
requirements:
|
31
38
|
- - ~>
|
32
39
|
- !ruby/object:Gem::Version
|
33
40
|
version: '1.6'
|
34
|
-
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack-cors
|
35
43
|
requirement: !ruby/object:Gem::Requirement
|
36
44
|
requirements:
|
37
45
|
- - ~>
|
38
46
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
40
|
-
|
41
|
-
- !ruby/object:Gem::Dependency
|
47
|
+
version: '0.2'
|
48
|
+
type: :runtime
|
42
49
|
prerelease: false
|
43
50
|
version_requirements: !ruby/object:Gem::Requirement
|
44
51
|
requirements:
|
45
52
|
- - ~>
|
46
53
|
- !ruby/object:Gem::Version
|
47
54
|
version: '0.2'
|
48
|
-
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack-parser
|
49
57
|
requirement: !ruby/object:Gem::Requirement
|
50
58
|
requirements:
|
51
59
|
- - ~>
|
52
60
|
- !ruby/object:Gem::Version
|
53
|
-
version: '0.
|
54
|
-
|
55
|
-
- !ruby/object:Gem::Dependency
|
61
|
+
version: '0.6'
|
62
|
+
type: :runtime
|
56
63
|
prerelease: false
|
57
64
|
version_requirements: !ruby/object:Gem::Requirement
|
58
65
|
requirements:
|
59
66
|
- - ~>
|
60
67
|
- !ruby/object:Gem::Version
|
61
68
|
version: '0.6'
|
62
|
-
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sinatra
|
63
71
|
requirement: !ruby/object:Gem::Requirement
|
64
72
|
requirements:
|
65
73
|
- - ~>
|
66
74
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Dependency
|
75
|
+
version: '1.4'
|
76
|
+
type: :runtime
|
70
77
|
prerelease: false
|
71
78
|
version_requirements: !ruby/object:Gem::Requirement
|
72
79
|
requirements:
|
73
80
|
- - ~>
|
74
81
|
- !ruby/object:Gem::Version
|
75
82
|
version: '1.4'
|
76
|
-
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: lz4-ruby
|
77
85
|
requirement: !ruby/object:Gem::Requirement
|
78
86
|
requirements:
|
79
87
|
- - ~>
|
80
88
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
82
|
-
|
83
|
-
- !ruby/object:Gem::Dependency
|
89
|
+
version: '0.3'
|
90
|
+
type: :runtime
|
84
91
|
prerelease: false
|
85
92
|
version_requirements: !ruby/object:Gem::Requirement
|
86
93
|
requirements:
|
87
94
|
- - ~>
|
88
95
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
90
|
-
|
96
|
+
version: '0.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bundler
|
91
99
|
requirement: !ruby/object:Gem::Requirement
|
92
100
|
requirements:
|
93
101
|
- - ~>
|
94
102
|
- !ruby/object:Gem::Version
|
95
103
|
version: '1.6'
|
96
|
-
|
97
|
-
- !ruby/object:Gem::Dependency
|
104
|
+
type: :development
|
98
105
|
prerelease: false
|
99
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.6'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - ~>
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '10.0'
|
104
118
|
type: :development
|
105
|
-
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
121
|
requirements:
|
107
122
|
- - ~>
|
108
123
|
- !ruby/object:Gem::Version
|
109
124
|
version: '10.0'
|
110
|
-
name: rake
|
111
125
|
description: Apache Cassandra web interface using Ruby, Event-machine, AngularJS,
|
112
126
|
Server-Sent-Events and DataStax Ruby driver for Apache Cassandra
|
113
127
|
email:
|
@@ -119,6 +133,7 @@ extra_rdoc_files: []
|
|
119
133
|
files:
|
120
134
|
- README.md
|
121
135
|
- app.rb
|
136
|
+
- app/helpers/async.rb
|
122
137
|
- app/helpers/json.rb
|
123
138
|
- app/helpers/sse.rb
|
124
139
|
- app/public/css/bootstrap-theme.css
|
@@ -156,17 +171,17 @@ require_paths:
|
|
156
171
|
- lib
|
157
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|
158
173
|
requirements:
|
159
|
-
- - '>='
|
174
|
+
- - ! '>='
|
160
175
|
- !ruby/object:Gem::Version
|
161
176
|
version: 1.9.3
|
162
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
178
|
requirements:
|
164
|
-
- - '>='
|
179
|
+
- - ! '>='
|
165
180
|
- !ruby/object:Gem::Version
|
166
181
|
version: '0'
|
167
182
|
requirements: []
|
168
183
|
rubyforge_project:
|
169
|
-
rubygems_version: 2.4.
|
184
|
+
rubygems_version: 2.4.2
|
170
185
|
signing_key:
|
171
186
|
specification_version: 4
|
172
187
|
summary: A simple web ui for Apache Cassandra
|