rewritten 0.5.0 → 0.6.0

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.
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: {}