rewritten 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/README.rdoc +93 -0
  4. data/Rakefile +28 -0
  5. data/bin/rewritten-web.rb +25 -0
  6. data/config.ru +4 -0
  7. data/lib/rack/dummy.rb +22 -0
  8. data/lib/rack/html.rb +44 -0
  9. data/lib/rack/record.rb +30 -0
  10. data/lib/rack/url.rb +47 -0
  11. data/lib/rewritten/config.ru +4 -0
  12. data/lib/rewritten/helpers.rb +58 -0
  13. data/lib/rewritten/server/public/favicon.ico +0 -0
  14. data/lib/rewritten/server/public/idle.png +0 -0
  15. data/lib/rewritten/server/public/jquery-1.3.2.min.js +19 -0
  16. data/lib/rewritten/server/public/jquery.relatize_date.js +95 -0
  17. data/lib/rewritten/server/public/poll.png +0 -0
  18. data/lib/rewritten/server/public/ranger.js +73 -0
  19. data/lib/rewritten/server/public/reset.css +48 -0
  20. data/lib/rewritten/server/public/style.css +85 -0
  21. data/lib/rewritten/server/public/working.png +0 -0
  22. data/lib/rewritten/server/test_helper.rb +19 -0
  23. data/lib/rewritten/server/views/clear_hits.erb +10 -0
  24. data/lib/rewritten/server/views/delete.erb +16 -0
  25. data/lib/rewritten/server/views/error.erb +1 -0
  26. data/lib/rewritten/server/views/failed.erb +64 -0
  27. data/lib/rewritten/server/views/hits.erb +30 -0
  28. data/lib/rewritten/server/views/key_sets.erb +19 -0
  29. data/lib/rewritten/server/views/key_string.erb +11 -0
  30. data/lib/rewritten/server/views/layout.erb +44 -0
  31. data/lib/rewritten/server/views/mappings.erb +61 -0
  32. data/lib/rewritten/server/views/new.erb +16 -0
  33. data/lib/rewritten/server/views/next_more.erb +11 -0
  34. data/lib/rewritten/server/views/overview.erb +8 -0
  35. data/lib/rewritten/server/views/queues.erb +49 -0
  36. data/lib/rewritten/server/views/stats.erb +62 -0
  37. data/lib/rewritten/server/views/to.erb +22 -0
  38. data/lib/rewritten/server/views/workers.erb +109 -0
  39. data/lib/rewritten/server/views/working.erb +72 -0
  40. data/lib/rewritten/server.rb +209 -0
  41. data/lib/rewritten/version.rb +3 -0
  42. data/lib/rewritten.rb +403 -0
  43. data/lib/test.ru +17 -0
  44. data/rewritten.gemspec +40 -0
  45. data/test/test_rewritten.rb +6 -0
  46. metadata +174 -0
@@ -0,0 +1,22 @@
1
+
2
+ <h1 class='wi'><%= params[:to] %> (App URL)</h1>
3
+
4
+ <a href="<%= u(%|/new?to=#{params[:to]}|) %>"> + add Another translation </a>
5
+
6
+ <table class='queues'>
7
+ <tr>
8
+ <th>Translations (Browser Location Bar) </th>
9
+ <th>Action</th>
10
+ </tr>
11
+
12
+ <% for translation in Rewritten.list_range("to:#{params[:to]}", 0, 100) %>
13
+ <tr>
14
+ <td class=''><a href="<%= translation %>" target="new"><%= translation %></td>
15
+ <td class=''><a href="<%= u("/delete?from=#{translation}&to=#{params[:to]}") %>">Delete</a></td>
16
+ </tr>
17
+ <% end %>
18
+
19
+ </table>
20
+
21
+
22
+
@@ -0,0 +1,109 @@
1
+ <% @subtabs = worker_hosts.keys.sort unless worker_hosts.size == 1 %>
2
+
3
+ <% if params[:id] && worker = Resque::Worker.find(params[:id]) %>
4
+
5
+ <h1>Worker <%= worker %></h1>
6
+ <table class='workers'>
7
+ <tr>
8
+ <th>&nbsp;</th>
9
+ <th>Host</th>
10
+ <th>Pid</th>
11
+ <th>Started</th>
12
+ <th>Queues</th>
13
+ <th>Processed</th>
14
+ <th>Failed</th>
15
+ <th>Processing</th>
16
+ </tr>
17
+ <tr>
18
+ <td class='icon'><img src="<%=u state = worker.state %>.png" alt="<%= state %>" title="<%= state %>"></td>
19
+
20
+ <% host, pid, queues = worker.to_s.split(':') %>
21
+ <td><%= host %></td>
22
+ <td><%= pid %></td>
23
+ <td><span class="time"><%= worker.started %></span></td>
24
+ <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
25
+ <td><%= worker.processed %></td>
26
+ <td><%= worker.failed %></td>
27
+ <td class='process'>
28
+ <% data = worker.processing || {} %>
29
+ <% if data['queue'] %>
30
+ <code><%= data['payload']['class'] %></code>
31
+ <small><a class="queue time" href="<%=u "/working/#{worker}" %>"><%= data['run_at'] %></a></small>
32
+ <% else %>
33
+ <span class='waiting'>Waiting for a job...</span>
34
+ <% end %>
35
+ </td>
36
+ </tr>
37
+ </table>
38
+
39
+ <% elsif params[:id] && !worker_hosts.keys.include?(params[:id]) && params[:id] != 'all' %>
40
+
41
+ <h1>Worker doesn't exist</h1>
42
+
43
+ <% elsif worker_hosts.size == 1 || params[:id] %>
44
+
45
+ <% if worker_hosts.size == 1 || params[:id] == 'all' %>
46
+ <% workers = Resque.workers %>
47
+ <% else %>
48
+ <% workers = worker_hosts[params[:id]].map { |id| Resque::Worker.find(id) } %>
49
+ <% end %>
50
+
51
+ <h1 class='wi'><%= workers.size %> Workers</h1>
52
+ <p class='intro'>The workers listed below are all registered as active on your system.</p>
53
+ <table class='workers'>
54
+ <tr>
55
+ <th>&nbsp;</th>
56
+ <th>Where</th>
57
+ <th>Queues</th>
58
+ <th>Processing</th>
59
+ </tr>
60
+ <% for worker in (workers = workers.sort_by { |w| w.to_s }) %>
61
+ <tr class="<%=state = worker.state%>">
62
+ <td class='icon'><img src="<%=u state %>.png" alt="<%= state %>" title="<%= state %>"></td>
63
+
64
+ <% host, pid, queues = worker.to_s.split(':') %>
65
+ <td class='where'><a href="<%=u "workers/#{worker}"%>"><%= host %>:<%= pid %></a></td>
66
+ <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
67
+
68
+ <td class='process'>
69
+ <% data = worker.processing || {} %>
70
+ <% if data['queue'] %>
71
+ <code><%= data['payload']['class'] %></code>
72
+ <small><a class="queue time" href="<%=u "/working/#{worker}" %>"><%= data['run_at'] %></a></small>
73
+ <% else %>
74
+ <span class='waiting'>Waiting for a job...</span>
75
+ <% end %>
76
+ </td>
77
+ </tr>
78
+ <% end %>
79
+ <% if workers.empty? %>
80
+ <tr>
81
+ <td colspan='4' class='no-data'>There are no registered workers</td>
82
+ </tr>
83
+ <% end %>
84
+ </table>
85
+ <%=poll%>
86
+
87
+ <% else %>
88
+ <% @subtabs = [] %>
89
+ <h1 class='wi'>Workers</h1>
90
+ <p class='intro'>The hostnames below all have registered workers. Select a hostname to view its workers, or "all" to see all workers.</p>
91
+ <table class='queues'>
92
+ <tr>
93
+ <th>Hostname</th>
94
+ <th>Workers</th>
95
+ </tr>
96
+ <% for hostname, workers in worker_hosts.sort_by { |h,w| h } %>
97
+ <tr>
98
+ <td class='queue'><a class="queue" href="<%= u "workers/#{hostname}" %>"><%= hostname %></a></td>
99
+ <td class='size'><%= workers.size %></td>
100
+ </tr>
101
+ <% end %>
102
+ <tr class="failed">
103
+ <td class='queue failed'><a class="queue" href="<%= u "workers/all" %>">all workers</a></td>
104
+ <td class='size'><%= Resque.workers.size %></td>
105
+ </tr>
106
+ </table>
107
+
108
+
109
+ <% end %>
@@ -0,0 +1,72 @@
1
+ <% if params[:id] && (worker = Resque::Worker.find(params[:id])) && worker.job %>
2
+ <h1><%= worker %>'s job</h1>
3
+
4
+ <table>
5
+ <tr>
6
+ <th>&nbsp;</th>
7
+ <th>Where</th>
8
+ <th>Queue</th>
9
+ <th>Started</th>
10
+ <th>Class</th>
11
+ <th>Args</th>
12
+ </tr>
13
+ <tr>
14
+ <td><img src="<%=u 'working.png' %>" alt="working" title="working"></td>
15
+ <% host, pid, _ = worker.to_s.split(':') %>
16
+ <td><a href="<%=u "/workers/#{worker}" %>"><%= host %>:<%= pid %></a></td>
17
+ <% data = worker.job %>
18
+ <% queue = data['queue'] %>
19
+ <td><a class="queue" href="<%=u "/queues/#{queue}" %>"><%= queue %></a></td>
20
+ <td><span class="time"><%= data['run_at'] %></span></td>
21
+ <td>
22
+ <code><%= data['payload']['class'] %></code>
23
+ </td>
24
+ <td><%=h data['payload']['args'].inspect %></td>
25
+ </tr>
26
+ </table>
27
+
28
+ <% else %>
29
+
30
+ <%
31
+ workers = resque.working
32
+ jobs = workers.collect {|w| w.job }
33
+ worker_jobs = workers.zip(jobs)
34
+ worker_jobs = worker_jobs.reject { |w, j| w.idle? }
35
+ %>
36
+
37
+ <h1 class='wi'><%= worker_jobs.size %> of <%= resque.workers.size %> Workers Working</h1>
38
+ <p class='intro'>The list below contains all workers which are currently running a job.</p>
39
+ <table class='workers'>
40
+ <tr>
41
+ <th>&nbsp;</th>
42
+ <th>Where</th>
43
+ <th>Queue</th>
44
+ <th>Processing</th>
45
+ </tr>
46
+ <% if worker_jobs.empty? %>
47
+ <tr>
48
+ <td colspan="4" class='no-data'>Nothing is happening right now...</td>
49
+ </tr>
50
+ <% end %>
51
+
52
+ <% worker_jobs.sort_by {|w, j| j['run_at'] ? j['run_at'] : '' }.each do |worker, job| %>
53
+ <tr>
54
+ <td class='icon'><img src="<%=u state = worker.state %>.png" alt="<%= state %>" title="<%= state %>"></td>
55
+ <% host, pid, queues = worker.to_s.split(':') %>
56
+ <td class='where'><a href="<%=u "/workers/#{worker}" %>"><%= host %>:<%= pid %></a></td>
57
+ <td class='queues queue'>
58
+ <a class="queue-tag" href="<%=u "/queues/#{job['queue']}" %>"><%= job['queue'] %></a>
59
+ </td>
60
+ <td class='process'>
61
+ <% if job['queue'] %>
62
+ <code><%= job['payload']['class'] %></code>
63
+ <small><a class="queue time" href="<%=u "/working/#{worker}" %>"><%= job['run_at'] %></a></small>
64
+ <% else %>
65
+ <span class='waiting'>Waiting for a job...</span>
66
+ <% end %>
67
+ </td>
68
+ </tr>
69
+ <% end %>
70
+ </table>
71
+
72
+ <% end %>
@@ -0,0 +1,209 @@
1
+ require 'sinatra/base'
2
+ require 'erb'
3
+ require 'rewritten'
4
+ require 'rewritten/version'
5
+ require 'time'
6
+
7
+ module Rewritten
8
+ class Server < Sinatra::Base
9
+
10
+ dir = File.dirname(File.expand_path(__FILE__))
11
+
12
+ set :views, "#{dir}/server/views"
13
+ set :public, "#{dir}/server/public"
14
+ set :static, true
15
+
16
+ helpers do
17
+ include Rack::Utils
18
+ alias_method :h, :escape_html
19
+
20
+ def current_section
21
+ url_path request.path_info.sub('/','').split('/')[0].downcase
22
+ end
23
+
24
+ def current_page
25
+ url_path request.path_info.sub('/','')
26
+ end
27
+
28
+ def url_path(*path_parts)
29
+ [ path_prefix, path_parts ].join("/").squeeze('/')
30
+ end
31
+ alias_method :u, :url_path
32
+
33
+ def path_prefix
34
+ request.env['SCRIPT_NAME']
35
+ end
36
+
37
+ def class_if_current(path = '')
38
+ 'class="current"' if current_page[0, path.size] == path
39
+ end
40
+
41
+ def tab(name)
42
+ dname = name.to_s.downcase
43
+ path = url_path(dname)
44
+ "<li #{class_if_current(path)}><a href='#{path}'>#{name}</a></li>"
45
+ end
46
+
47
+ def tabs
48
+ Rewritten::Server.tabs
49
+ end
50
+
51
+ def redis_get_size(key)
52
+ case Resque.redis.type(key)
53
+ when 'none'
54
+ []
55
+ when 'list'
56
+ Resque.redis.llen(key)
57
+ when 'set'
58
+ Resque.redis.scard(key)
59
+ when 'string'
60
+ Resque.redis.get(key).length
61
+ when 'zset'
62
+ Resque.redis.zcard(key)
63
+ end
64
+ end
65
+
66
+ def redis_get_value_as_array(key, start=0)
67
+ case Resque.redis.type(key)
68
+ when 'none'
69
+ []
70
+ when 'list'
71
+ Resque.redis.lrange(key, start, start + 20)
72
+ when 'set'
73
+ Resque.redis.smembers(key)[start..(start + 20)]
74
+ when 'string'
75
+ [Resque.redis.get(key)]
76
+ when 'zset'
77
+ Resque.redis.zrange(key, start, start + 20)
78
+ end
79
+ end
80
+
81
+ def show_args(args)
82
+ Array(args).map { |a| a.inspect }.join("\n")
83
+ end
84
+
85
+ def worker_hosts
86
+ @worker_hosts ||= worker_hosts!
87
+ end
88
+
89
+ def worker_hosts!
90
+ hosts = Hash.new { [] }
91
+
92
+ Resque.workers.each do |worker|
93
+ host, _ = worker.to_s.split(':')
94
+ hosts[host] += [worker.to_s]
95
+ end
96
+
97
+ hosts
98
+ end
99
+
100
+ def partial?
101
+ @partial
102
+ end
103
+
104
+ def partial(template, local_vars = {})
105
+ @partial = true
106
+ erb(template.to_sym, {:layout => false}, local_vars)
107
+ ensure
108
+ @partial = false
109
+ end
110
+
111
+ def poll
112
+ if @polling
113
+ text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
114
+ else
115
+ text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll</a>"
116
+ end
117
+ "<p class='poll'>#{text}</p>"
118
+ end
119
+
120
+ end # enf of helpers
121
+
122
+
123
+ def show(page, layout = true)
124
+ begin
125
+ erb page.to_sym, {:layout => layout}, :rewritten => Rewritten
126
+ rescue Errno::ECONNREFUSED
127
+ erb :error, {:layout => false}, :error => "Can't connect to Redis! (#{Rewritten.redis_id})"
128
+ end
129
+ end
130
+
131
+ def show_for_polling(page)
132
+ content_type "text/html"
133
+ @polling = true
134
+ show(page.to_sym, false).gsub(/\s{1,}/, ' ')
135
+ end
136
+
137
+
138
+ ################################################################################
139
+
140
+
141
+ get "/?" do
142
+ redirect url_path(:overview)
143
+ end
144
+
145
+ get "/overview" do
146
+ show 'overview'
147
+ end
148
+
149
+ get "/new" do
150
+ show "new"
151
+ end
152
+
153
+ post "/mappings" do
154
+ if params[:from]!='' && params[:to]!=''
155
+ Rewritten.add_translation(params[:from], params[:to])
156
+ redirect u('overview')
157
+ else
158
+ show "new"
159
+ end
160
+ end
161
+
162
+ get "/to" do
163
+ translations = Rewritten.list_range(params[:to], 0, -1)
164
+ show "to"
165
+ end
166
+
167
+ get "/delete" do
168
+ @from = params[:from]
169
+ @to = params[:to]
170
+ show "delete"
171
+ end
172
+
173
+ post '/delete' do
174
+
175
+ from = params[:from]
176
+ to = params[:to]
177
+
178
+ Rewritten.remove_translation(from, to)
179
+
180
+ if Rewritten.num_translations(to) > 0
181
+ redirect u("/to?to=#{to}")
182
+ else
183
+ redirect u("/")
184
+ end
185
+
186
+ end
187
+
188
+ get "/hits" do
189
+ show "hits"
190
+ end
191
+
192
+ get "/hits/clear" do
193
+ show "clear_hits"
194
+ end
195
+
196
+ post "/hits/clear" do
197
+ Rewritten.redis.del("hits")
198
+ redirect u("/hits")
199
+ end
200
+
201
+ def self.tabs
202
+ #@tabs ||= ["Overview", "Working", "Failed", "Queues", "Workers", "Stats"]
203
+ @tabs ||= ["Overview", "Hits"]
204
+ end
205
+
206
+ end
207
+ end
208
+
209
+
@@ -0,0 +1,3 @@
1
+ module Rewritten
2
+ VERSION = "0.0.1"
3
+ end