rewritten 0.0.1

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.
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