skvs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in skvs.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/skvs ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "skvs"
4
+
5
+ Sinatra::Application.run!(:port => 7654)
@@ -0,0 +1,3 @@
1
+ module Skvs
2
+ VERSION = "0.0.1"
3
+ end
data/lib/skvs.rb ADDED
@@ -0,0 +1,73 @@
1
+ require "skvs/version"
2
+ require "sinatra"
3
+ require "redis"
4
+ require "cgi"
5
+
6
+ get "/" do
7
+ keys = redis.keys("skvs:#{params[:q]}*").sort
8
+ @count = keys.count
9
+ keys = keys.first(load_count + 1)
10
+
11
+ if keys.size > load_count
12
+ keys.pop
13
+ @oversized = true
14
+ end
15
+
16
+ if keys.any?
17
+ values = redis.mget(*keys)
18
+ @data = keys.map{|k| k.split(":", 2).last }.zip(values)
19
+ else
20
+ @data = []
21
+ end
22
+
23
+ erb :index
24
+ end
25
+
26
+ get "/*" do
27
+ content_type "text/plain"
28
+ redis_get params[:splat]
29
+ end
30
+
31
+ put "/*" do
32
+ redis_set params[:splat], request.body.read
33
+ nil
34
+ end
35
+
36
+ post "/_set" do
37
+ redis_set params[:key], params[:value]
38
+ redirect url("/")
39
+ end
40
+
41
+ helpers do
42
+ def load_count
43
+ [params[:load_count].to_i, 5].max
44
+ end
45
+
46
+ def h(v)
47
+ CGI.escapeHTML(v)
48
+ end
49
+
50
+ def hbr(v)
51
+ CGI.escapeHTML(v).gsub("\n", "\n<br/>")
52
+ end
53
+
54
+ def key(*k)
55
+ "skvs:#{k.flatten.join("/")}"
56
+ end
57
+
58
+ def redis
59
+ @redis ||= Redis.new
60
+ end
61
+
62
+ def redis_set(k, v)
63
+ if v.to_s == ""
64
+ redis.del key(*k)
65
+ else
66
+ redis.set key(*k), v
67
+ end
68
+ end
69
+
70
+ def redis_get(k)
71
+ redis.get key(k)
72
+ end
73
+ end
@@ -0,0 +1,173 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ table{
5
+ border-collapse:separate;
6
+ border-spacing: 0 20px;
7
+
8
+ width: 100%;
9
+ }
10
+
11
+ table td, table th{
12
+ width: 50%;
13
+ padding: 0 10px;
14
+ }
15
+
16
+ table tfoot a{
17
+ text-decoration: underline;
18
+ }
19
+
20
+ table td{
21
+ border-left: 1px solid #eee;
22
+ }
23
+
24
+ table th{
25
+ text-align: right;
26
+ font-weight: bold;
27
+ border-right: 1px solid #fff;
28
+ }
29
+
30
+ table tr:hover th{
31
+ border-right: 1px solid #eee;
32
+ }
33
+
34
+ * {
35
+ font-weight: inherit;
36
+ text-decoration: inherit;
37
+ color: inherit;
38
+ }
39
+ strong {
40
+ font-weight: bold;
41
+ }
42
+
43
+ body {
44
+ font-family: "helvetica neue", arial, sans-serif;
45
+ font-weight: 200;
46
+ }
47
+
48
+ #search, tfoot {
49
+ text-align: center;
50
+ }
51
+
52
+ h1, td *, th *, th, td{
53
+ vertical-align: top;
54
+ }
55
+
56
+ h1 {
57
+ text-align: center;
58
+ font-weight: bold;
59
+ }
60
+ textarea {
61
+ padding: 2px;
62
+ }
63
+
64
+ </style>
65
+ <title>Simple Key/Value Store (SKVS)</title>
66
+ </head>
67
+ <body>
68
+ <h1>Simple Key/Value Store (SKVS)</h1>
69
+
70
+ <form id="search" method="get" action="<%= url("/") %>">
71
+ <input type='search' placeholder='search' name='q' value="<%=h params[:q].to_s %>" />
72
+ </form>
73
+
74
+ <form id="main" method="post" action="<%= url("/_set") %>">
75
+
76
+ <table id="data">
77
+ <thead>
78
+ <tr>
79
+ <th>
80
+ <input form="main" name="key" placeholder="key" required />
81
+ </th>
82
+ <td>
83
+ <textarea form="main" name="value" placeholder="value" ></textarea>
84
+ <input form="main" type="submit" value="set" />
85
+ </td>
86
+ </tr>
87
+ </thead>
88
+ <tfoot>
89
+ <tr>
90
+ <td colspan="2">
91
+ <% if @count > load_count %>
92
+ Showing <strong><%= load_count %></strong> of <strong><%= @count %></strong>,
93
+ <a href="<%= url("/?load_count=#{load_count*2}&q=#{URI.encode(params[:q].to_s)}") %>">
94
+ load more?
95
+ </a>
96
+ <% else %>
97
+ Showing all <strong><%= @count %></strong>.
98
+ <% end %>
99
+ </td>
100
+ </tr>
101
+ </tfoot>
102
+ <tbody>
103
+ <% @data.each do |k,v| %>
104
+ <tr>
105
+ <th><a href="<%= url("/#{k}") %>"><%=h k %></a></th>
106
+ <% if v.length < 100 %>
107
+ <td><%=hbr v %></td>
108
+ <% else %>
109
+ <td class="truncated"><%=hbr v[0..100] %>...</td>
110
+ <% end %>
111
+ </tr>
112
+ <% end %>
113
+ </tbody>
114
+ </table>
115
+
116
+ </form>
117
+
118
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript" charset="utf-8"></script>
119
+
120
+ <script type="text/javascript" charset="utf-8">
121
+ $(function(){
122
+ $("input[name=key]").focus();
123
+ $("tbody").on("click", "td", function(){
124
+ var $t = $(this),
125
+ key = $t.parent("tr").find("th").text();
126
+
127
+ if($t.hasClass("truncated")){
128
+ $.get(<%= url("/").inspect %>+key, function(value){
129
+ $("input[name=key]").val(key);
130
+ $("textarea[name=value]").val(value).focus().select();
131
+ });
132
+ }else{
133
+ $("input[name=key]").val(key);
134
+ $("textarea[name=value]").val($t.text()).focus().select();
135
+ }
136
+ });
137
+
138
+
139
+ var update = function(url){
140
+ $.get(url, function(data){
141
+ var doc = $(data);
142
+ $("#data tbody").replaceWith(doc.find("#data tbody"));
143
+ $("#data tfoot").replaceWith(doc.find("#data tfoot"));
144
+ $("#search input").val(doc.find("input[type=search]").val());
145
+ });
146
+ }
147
+
148
+
149
+ var oldUrl = null;
150
+ var seachCallback = function(el){
151
+ var url = "/?q="+encodeURIComponent($(this).val());
152
+ if(oldUrl === url){
153
+ return;
154
+ }
155
+ oldUrl = url;
156
+ window.history.pushState({}, "", url);
157
+ update(url);
158
+ };
159
+
160
+ $(window).on("popstate", function(){
161
+ update(document.location);
162
+ })
163
+
164
+ $("#search input")
165
+ .on("keyup", seachCallback)
166
+ .on("change", seachCallback)
167
+ .on("search", seachCallback);
168
+
169
+ });
170
+ </script>
171
+
172
+ </body>
173
+ </html>
data/readme.markdown ADDED
@@ -0,0 +1,34 @@
1
+ SKVS - Simple Key/Value Store
2
+ =============================
3
+
4
+ A dirt simple HTTP key value store, with a fancy UI.
5
+
6
+ Usage
7
+ -----
8
+ 1. Install the gem:
9
+
10
+ $ gem install skvs
11
+
12
+ 2. Start the server:
13
+
14
+ $ skvs
15
+
16
+ 3. Navigate the the UI:
17
+
18
+ [http://localhost:7654/](http://localhost:7654/)
19
+
20
+
21
+ Example Bash Client
22
+ -------------------
23
+
24
+ function skvs_pull(){
25
+ echo $(curl -s -o - "http://localhost:7654/$1")
26
+ }
27
+
28
+ function skvs_push(){
29
+ local key
30
+ key=$1
31
+ shift
32
+ curl -XPUT --data-binary "$*" -s -o /dev/null "http://localhost:7654/$key"
33
+ }
34
+
data/skvs.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "skvs/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "skvs"
7
+ s.version = Skvs::VERSION
8
+ s.authors = ["Tom Lea"]
9
+ s.email = ["commit@tomlea.co.uk"]
10
+ s.homepage = ""
11
+ s.summary = %q{Simple Key/Value Store}
12
+ s.description = %q{A dirt simple HTTP key value store, with a fancy UI.
13
+ }
14
+
15
+ s.rubyforge_project = "skvs"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency "redis"
23
+ s.add_runtime_dependency "sinatra"
24
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skvs
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Tom Lea
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-02-09 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: redis
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: sinatra
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ description: "A dirt simple HTTP key value store, with a fancy UI.\n "
49
+ email:
50
+ - commit@tomlea.co.uk
51
+ executables:
52
+ - skvs
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - Gemfile
60
+ - Rakefile
61
+ - bin/skvs
62
+ - lib/skvs.rb
63
+ - lib/skvs/version.rb
64
+ - lib/views/index.erb
65
+ - readme.markdown
66
+ - skvs.gemspec
67
+ homepage: ""
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options: []
72
+
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ hash: 3
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ requirements: []
94
+
95
+ rubyforge_project: skvs
96
+ rubygems_version: 1.8.13
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Simple Key/Value Store
100
+ test_files: []
101
+