rewritten 0.5.0 → 0.6.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: 7457fe2750b09f702f64e2255515fcb1b7d681f1
4
- data.tar.gz: a7653f8eb5b983e220f4332d6395d0f17fec6e4a
3
+ metadata.gz: 4bbca7b948eee5641bd22eb57aec66f65a2501fc
4
+ data.tar.gz: 9eba6f5b82e869fef3c50a487f8ba0e60f793d3e
5
5
  SHA512:
6
- metadata.gz: e0f1fb6a8ee92c5517963ec40e34d7ac286312ae4382049c9b10209e3402b6a858d7d9346abd06fc0925ad3124c9a7c6f5523f0ddaf9e603d3d9215c66b5020e
7
- data.tar.gz: 23194964b145fe819f7aa68a6bc327661f932483a5046d16d9868604c350be7fc829cf2c6c82aaa0e77dc953f05e57fa0ef8d403fb96b98af7afb3b200ec9351
6
+ metadata.gz: 7b0ab0e5fc9379e0ea051040a864fbdeb5f78662fa92f24d9d15bc3c933a78313518160f2e0c20cce80bfbe36d4ec62d3cb9bde81eb3bb24dfc4f31f6ea66331
7
+ data.tar.gz: 4b237a6666a91216654ac7f894bce5882dbcf73274e8cc07b9ed237f2be64c9e987663ca2106fde7c783957c13706ac800f3e5fdf13b1065523538d80b796df3
data/HISTORY.rdoc CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.6.0
2
+
3
+ * backwards translations (from resource to current translation)
4
+
1
5
  == 0.5.0
2
6
 
3
7
  * dump and import scripts in bin/
data/lib/rack/url.rb CHANGED
@@ -8,8 +8,9 @@ module Rack
8
8
 
9
9
  def initialize(app, &block)
10
10
  @app = app
11
+ @translate_backwards = false
11
12
 
12
- self.instance_eval(&block) if block_given?
13
+ instance_eval(&block) if block_given?
13
14
  end
14
15
 
15
16
  def call(env)
@@ -17,7 +18,12 @@ module Rack
17
18
 
18
19
  subdomain = env["SUBDOMAIN"] ? "#{env["SUBDOMAIN"]}:" : ""
19
20
 
20
- if to = ::Rewritten.includes?("#{subdomain}#{req.path_info}")
21
+ path = "#{subdomain}#{req.path_info}"
22
+
23
+ if ::Rewritten.includes?(path) or translate_backwards? && ::Rewritten.exist_translation_for?(path)
24
+
25
+ to = ::Rewritten.includes?(path) || path
26
+
21
27
  current_path = ::Rewritten.get_current_translation(to)
22
28
  current_path = current_path.split(":").last
23
29
 
@@ -42,7 +48,7 @@ module Rack
42
48
  r.redirect(new_path, 301)
43
49
  a = r.finish
44
50
  end
45
- else
51
+ else
46
52
  @app.call(req.env)
47
53
  end
48
54
  end
@@ -54,10 +60,13 @@ module Rack
54
60
 
55
61
 
56
62
  private
63
+
64
+ def translate_backwards?
65
+ @translate_backwards
66
+ end
57
67
 
58
- def add_translation(from,to)
59
- ::Rewritten.redis = :test unless ::Rewritten.redis == :test
60
- ::Rewritten.add_translation(from, to)
68
+ def translate_backwards=(yes_or_no)
69
+ @translate_backwards = yes_or_no
61
70
  end
62
71
 
63
72
 
@@ -153,6 +153,7 @@ module Rewritten
153
153
 
154
154
  if params[:f] && params[:f] != ""
155
155
  @translations = []
156
+
156
157
  keys = Rewritten.redis.keys("*#{params[:f]}*")
157
158
  keys.each do |key|
158
159
  prefix, url = key.split(":")
@@ -164,12 +165,13 @@ module Rewritten
164
165
  @translations << [from, url]
165
166
  end
166
167
  end
168
+
167
169
  @size = @translations.size
168
170
  @translations = @translations[params[:start].to_i..params[:start].to_i+Rewritten.per_page-1]
169
171
 
170
172
  else
171
- @size = Rewritten.size("froms")
172
- froms = Rewritten.list_range("froms", @start, Rewritten.per_page)
173
+ @size = Rewritten.num_froms
174
+ froms = Rewritten.all_froms[@start, @start+Rewritten.per_page-1]
173
175
  @translations = froms.map{|f| [f, Rewritten.redis.get("from:#{f}")]}
174
176
  end
175
177
 
@@ -227,7 +229,7 @@ module Rewritten
227
229
  get "/cleanup" do
228
230
  # find keys that have no target
229
231
  @from_without_tos= []
230
- Rewritten.redis.lrange("froms", 0, -1).each do |from|
232
+ Rewritten.all_froms.each do |from|
231
233
  if Rewritten.redis.get("from:#{from}").empty?
232
234
  @from_without_tos << from
233
235
  end
@@ -1,4 +1,4 @@
1
1
  module Rewritten
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
4
4
 
data/lib/rewritten.rb CHANGED
@@ -35,9 +35,6 @@ module Rewritten
35
35
  @redis = Redis::Namespace.new(namespace, :redis => redis)
36
36
  when Redis::Namespace
37
37
  @redis = server
38
- when :test
39
- @redis = :test
40
- @static_translations = {}
41
38
  else
42
39
  @redis = Redis::Namespace.new(:rewritten, :redis => server)
43
40
  end
@@ -130,14 +127,10 @@ module Rewritten
130
127
  #
131
128
 
132
129
  def add_translation(from, to)
133
- if @redis == :test
134
- @static_translations[from] = to
135
- else
136
- redis.set("from:#{from}", to)
137
- redis.lpush(:froms, from)
138
- redis.lpush(:tos, to)
139
- redis.rpush("to:#{to}", from)
140
- end
130
+ redis.set("from:#{from}", to)
131
+ redis.sadd(:froms, from)
132
+ redis.sadd(:tos, to)
133
+ redis.rpush("to:#{to}", from)
141
134
  end
142
135
 
143
136
  def add_translations(to, froms)
@@ -145,14 +138,14 @@ module Rewritten
145
138
  end
146
139
 
147
140
  def num_translations(to)
148
- Rewritten.size("to:#{to}")
141
+ Rewritten.redis.llen("to:#{to}")
149
142
  end
150
143
 
151
144
  def remove_translation(from, to)
152
145
  Rewritten.redis.del("from:#{from}")
153
- Rewritten.redis.lrem("froms", 0, from)
146
+ Rewritten.redis.srem(:froms, from)
154
147
  Rewritten.redis.lrem("to:#{to}", 0, from)
155
- Rewritten.redis.lrem("tos", 0, to) if num_translations(to) == 0
148
+ Rewritten.redis.srem(:tos, to) if num_translations(to) == 0
156
149
  end
157
150
 
158
151
  def remove_all_translations(to)
@@ -162,20 +155,20 @@ module Rewritten
162
155
  end
163
156
 
164
157
  def clear_translations
165
- if Rewritten.redis == :test
166
- @static_translations = {}
167
- else
168
- Rewritten.redis.del(*Rewritten.redis.keys) unless Rewritten.redis.keys.empty?
169
- end
158
+ Rewritten.redis.del(*Rewritten.redis.keys) unless Rewritten.redis.keys.empty?
159
+ end
160
+
161
+ # Returns an array of all known source URLs (that are to translated)
162
+ def froms
163
+ Array(redis.smembers(:froms))
164
+ end
165
+
166
+ def all_froms
167
+ Array(redis.smembers(:froms))
170
168
  end
171
169
 
172
170
  def all_tos
173
- tos = []
174
- if Rewritten.redis == :test
175
- tos = @static_translations.values.uniq
176
- else
177
- tos = Rewritten.redis.lrange("tos",0,-1).uniq
178
- end
171
+ Array(Rewritten.redis.smembers(:tos))
179
172
  end
180
173
 
181
174
  def all_translations
@@ -183,32 +176,18 @@ module Rewritten
183
176
  end
184
177
 
185
178
  def get_all_translations(to)
186
- if Rewritten.redis == :test
187
- @static_translations.to_a.select{|k,v| v == to}.map{|k,v| k}
188
- else
189
- Rewritten.redis.lrange("to:#{to}", 0, -1)
190
- end
179
+ Rewritten.redis.lrange("to:#{to}", 0, -1)
191
180
  end
192
181
 
193
182
  def get_current_translation(path)
194
- if @redis == :test
195
-
196
- translations = @static_translations.select{|k,v| v == path}
197
-
198
- if translations.size > 0
199
- return translations.keys.last
200
- else
201
- return path
202
- end
203
-
204
- else
205
- translation = Rewritten.list_range("to:#{path}", -1)
206
- return translation if translation
207
- return path
208
- end
183
+ translation = Rewritten.list_range("to:#{path}", -1)
184
+ return translation if translation
185
+ return path
209
186
  end
210
187
 
211
-
188
+ def exist_translation_for?(path)
189
+ get_current_translation(path) != path
190
+ end
212
191
 
213
192
  def add_hit(path, code, content_type)
214
193
  h = {:path => path, :code => code, :content_type => content_type}
@@ -220,61 +199,12 @@ module Rewritten
220
199
  end
221
200
 
222
201
  def includes?(path)
223
- if @redis == :test
224
- @static_translations[path]
225
- else
226
- Rewritten.redis.get("from:#{path}")
227
- end
228
- end
229
-
230
- #
231
- # queue manipulation
232
- #
233
-
234
- # Pushes a job onto a queue. Queue name should be a string and the
235
- # item should be any JSON-able Ruby object.
236
- #
237
- # Resque works generally expect the `item` to be a hash with the following
238
- # keys:
239
- #
240
- # class - The String name of the job to run.
241
- # args - An Array of arguments to pass the job. Usually passed
242
- # via `class.to_class.perform(*args)`.
243
- #
244
- # Example
245
- #
246
- # Resque.push('archive', :class => 'Archive', :args => [ 35, 'tar' ])
247
- #
248
- # Returns nothing
249
- def push(queue, item)
250
- watch_queue(queue)
251
- redis.rpush "queue:#{queue}", encode(item)
202
+ Rewritten.redis.get("from:#{path}")
252
203
  end
253
204
 
254
- # Pops a job off a queue. Queue name should be a string.
255
- #
256
- # Returns a Ruby object.
257
- def pop(queue)
258
- decode redis.lpop("queue:#{queue}")
259
- end
260
-
261
- # Returns an integer representing the size of translations for a target.
262
- # Target name should be a string.
263
- def size(target)
264
- #redis.llen("target:#{target}").to_i
265
- redis.llen(target).to_i
266
- end
267
-
268
- # Returns an array of items currently queued. Queue name should be
269
- # a string.
270
- #
271
- # start and count should be integer and can be used for pagination.
272
- # start is the item to begin, count is how many items to return.
273
- #
274
- # To get the 3rd page of a 30 item, paginatied list one would use:
275
- # Resque.peek('my_list', 59, 30)
276
- def peek(queue, start = 0, count = 1)
277
- list_range("queue:#{queue}", start, count)
205
+ # return the number of froms
206
+ def num_froms
207
+ redis.scard(:froms).to_i
278
208
  end
279
209
 
280
210
  # Does the dirty work of fetching a range of items from a Redis list
@@ -301,13 +231,6 @@ module Rewritten
301
231
  Array(redis.smembers(:targets))
302
232
  end
303
233
 
304
- # Returns an array of all known source URLs (that are to translated)
305
- def froms
306
- Array(redis.smembers(:froms))
307
- end
308
-
309
-
310
-
311
234
  # Given a queue name, completely deletes the queue.
312
235
  def remove_queue(queue)
313
236
  redis.srem(:queues, queue.to_s)
@@ -320,118 +243,7 @@ module Rewritten
320
243
  redis.sadd(:queues, queue.to_s)
321
244
  end
322
245
 
323
-
324
- #
325
- # job shortcuts
326
- #
327
-
328
- # This method can be used to conveniently add a job to a queue.
329
- # It assumes the class you're passing it is a real Ruby class (not
330
- # a string or reference) which either:
331
- #
332
- # a) has a @queue ivar set
333
- # b) responds to `queue`
334
- #
335
- # If either of those conditions are met, it will use the value obtained
336
- # from performing one of the above operations to determine the queue.
337
- #
338
- # If no queue can be inferred this method will raise a `Resque::NoQueueError`
339
- #
340
- # This method is considered part of the `stable` API.
341
- def enqueue(klass, *args)
342
- Job.create(queue_from_class(klass), klass, *args)
343
-
344
- Plugin.after_enqueue_hooks(klass).each do |hook|
345
- klass.send(hook, *args)
346
- end
347
- end
348
-
349
- # This method can be used to conveniently remove a job from a queue.
350
- # It assumes the class you're passing it is a real Ruby class (not
351
- # a string or reference) which either:
352
- #
353
- # a) has a @queue ivar set
354
- # b) responds to `queue`
355
- #
356
- # If either of those conditions are met, it will use the value obtained
357
- # from performing one of the above operations to determine the queue.
358
- #
359
- # If no queue can be inferred this method will raise a `Resque::NoQueueError`
360
- #
361
- # If no args are given, this method will dequeue *all* jobs matching
362
- # the provided class. See `Resque::Job.destroy` for more
363
- # information.
364
- #
365
- # Returns the number of jobs destroyed.
366
- #
367
- # Example:
368
- #
369
- # # Removes all jobs of class `UpdateNetworkGraph`
370
- # Resque.dequeue(GitHub::Jobs::UpdateNetworkGraph)
371
- #
372
- # # Removes all jobs of class `UpdateNetworkGraph` with matching args.
373
- # Resque.dequeue(GitHub::Jobs::UpdateNetworkGraph, 'repo:135325')
374
- #
375
- # This method is considered part of the `stable` API.
376
- def dequeue(klass, *args)
377
- Job.destroy(queue_from_class(klass), klass, *args)
378
- end
379
-
380
- # Given a class, try to extrapolate an appropriate queue based on a
381
- # class instance variable or `queue` method.
382
- def queue_from_class(klass)
383
- klass.instance_variable_get(:@queue) ||
384
- (klass.respond_to?(:queue) and klass.queue)
385
- end
386
-
387
- # This method will return a `Resque::Job` object or a non-true value
388
- # depending on whether a job can be obtained. You should pass it the
389
- # precise name of a queue: case matters.
390
- #
391
- # This method is considered part of the `stable` API.
392
- def reserve(queue)
393
- Job.reserve(queue)
394
- end
395
-
396
- # Validates if the given klass could be a valid Resque job
397
- #
398
- # If no queue can be inferred this method will raise a `Resque::NoQueueError`
399
- #
400
- # If given klass is nil this method will raise a `Resque::NoClassError`
401
- def validate(klass, queue = nil)
402
- queue ||= queue_from_class(klass)
403
-
404
- if !queue
405
- raise NoQueueError.new("Jobs must be placed onto a queue.")
406
- end
407
-
408
- if klass.to_s.empty?
409
- raise NoClassError.new("Jobs must be given a class.")
410
- end
411
- end
412
-
413
-
414
- #
415
- # worker shortcuts
416
- #
417
-
418
- # A shortcut to Worker.all
419
- def workers
420
- Worker.all
421
- end
422
-
423
- # A shortcut to Worker.working
424
- def working
425
- Worker.working
426
- end
427
-
428
- # A shortcut to unregister_worker
429
- # useful for command line tool
430
- def remove_worker(worker_id)
431
- worker = Resque::Worker.find(worker_id)
432
- worker.unregister_worker
433
- end
434
-
246
+
435
247
  #
436
248
  # stats
437
249
  #
@@ -1,7 +1,4 @@
1
- require 'rewritten'
2
- require 'rack/mock'
3
- require 'minitest/autorun'
4
- require 'pry'
1
+ require 'test_helper'
5
2
 
6
3
  describe Rack::Rewritten::Url do
7
4
 
@@ -15,16 +12,21 @@ describe Rack::Rewritten::Url do
15
12
  'rack.url_scheme' => 'http'}.merge(overrides)
16
13
  end
17
14
 
15
+ before {
16
+ Rewritten.add_translation '/foo/bar', '/products/1'
17
+ Rewritten.add_translation '/foo/baz', '/products/1'
18
+ Rewritten.add_translation '/foo/with/params', '/products/2?w=1'
19
+ }
20
+
18
21
  describe "redirection behavior" do
19
22
 
20
23
  before {
21
24
  @app = MiniTest::Mock.new
25
+ @rack = Rack::Rewritten::Url.new(@app)
22
26
 
23
- @rack = Rack::Rewritten::Url.new(@app) do
24
- add_translation '/foo/bar', '/products/1'
25
- add_translation '/foo/baz', '/products/1'
26
- add_translation '/foo/with/params', '/products/2?w=1'
27
- end
27
+ Rewritten.add_translation '/foo/bar', '/products/1'
28
+ Rewritten.add_translation '/foo/baz', '/products/1'
29
+ Rewritten.add_translation '/foo/with/params', '/products/2?w=1'
28
30
  }
29
31
 
30
32
  it "must not redirect if there are no entries" do
@@ -33,7 +35,7 @@ describe Rack::Rewritten::Url do
33
35
  @app.verify
34
36
  end
35
37
 
36
- it "must 301 redirect to latest translation" do
38
+ it "must 301 redirect from old translation to latest translation" do
37
39
  ret = @rack.call( call_args.merge('REQUEST_URI' => '/foo/bar', 'PATH_INFO' => '/foo/bar' ))
38
40
  @app.verify
39
41
  ret[0].must_equal 301
@@ -47,7 +49,6 @@ describe Rack::Rewritten::Url do
47
49
  ret[1]['Location'].must_equal "http://www.example.org/foo/baz?w=1"
48
50
  end
49
51
 
50
-
51
52
  it "must stay on latest translation" do
52
53
  @app.expect :call, [200, {'Content-Type' => 'text/plain'},[""]], [Hash]
53
54
  ret = @rack.call( call_args.merge('REQUEST_URI' => '/foo/baz', 'PATH_INFO' => '/foo/baz' ))
@@ -55,9 +56,33 @@ describe Rack::Rewritten::Url do
55
56
  ret[0].must_equal 200
56
57
  end
57
58
 
59
+ describe "enforce nice urls" do
60
+
61
+ it "must not redirect from resource url to nice url by default" do
62
+ @app.expect :call, [200, {'Content-Type' => 'text/plain'},[""]], [Hash]
63
+ ret = @rack.call( call_args.merge('REQUEST_URI' => '/products/1', 'PATH_INFO' => '/products/1' ))
64
+ @app.verify
65
+ ret[0].must_equal 200
66
+ end
67
+
68
+ it "must redirect from resource url to nice url if enabled xxx" do
69
+ @rack = Rack::Rewritten::Url.new(@app) do
70
+ self.translate_backwards = true
71
+ end
72
+
73
+ ret = @rack.call( call_args.merge('REQUEST_URI' => '/products/1', 'PATH_INFO' => '/products/1' ))
74
+ @app.verify
75
+ ret[0].must_equal 301
76
+ ret[1]['Location'].must_equal "http://www.example.org/foo/baz"
77
+ end
78
+
79
+ end
80
+
81
+
58
82
  end
59
83
 
60
84
 
85
+
61
86
  describe "the env" do
62
87
 
63
88
  before {
@@ -1,18 +1,15 @@
1
- require 'rewritten'
2
- require 'minitest/autorun'
1
+ require 'test_helper'
3
2
 
4
3
  describe Rewritten do
5
4
 
6
5
  before{
7
- Rewritten.redis = :test
8
- Rewritten.clear_translations
9
6
  Rewritten.add_translation('/from', '/to')
10
7
  Rewritten.add_translation('/from2', '/to')
11
8
  Rewritten.add_translation('/from3', '/to2')
12
9
  }
13
10
 
14
11
  it "must give all tos" do
15
- Rewritten.all_tos.must_equal ["/to", "/to2"]
12
+ Rewritten.all_tos.sort.must_equal ["/to", "/to2"]
16
13
  end
17
14
 
18
15
  it "must return all translations" do
@@ -0,0 +1,16 @@
1
+ require 'rewritten'
2
+ require 'minitest/autorun'
3
+ require 'pry'
4
+
5
+ class Minitest::Spec
6
+
7
+ before :each do
8
+ Rewritten.redis = "localhost:6379/test_rewritten"
9
+ Rewritten.clear_translations
10
+ end
11
+
12
+ after :each do
13
+ Rewritten.clear_translations
14
+ end
15
+
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rewritten
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kai Rubarth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-12 00:00:00.000000000 Z
11
+ date: 2013-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-namespace
@@ -182,6 +182,7 @@ files:
182
182
  - rewritten.gemspec
183
183
  - test/rack/rewritten_url_test.rb
184
184
  - test/rewritten_test.rb
185
+ - test/test_helper.rb
185
186
  homepage: ''
186
187
  licenses: []
187
188
  metadata: {}