Module: Rewritten

Extended by:
Rewritten
Includes:
Helpers
Included in:
Rewritten
Defined in:
lib/rewritten.rb,
lib/rewritten/server.rb,
lib/rewritten/helpers.rb,
lib/rewritten/version.rb,
lib/rewritten/document.rb,
lib/rewritten/rails/url_helpers.rb

Defined Under Namespace

Modules: Document, Helpers, Rails Classes: Server

Constant Summary collapse

VERSION =
"0.14.1"

Instance Method Summary collapse

Methods included from Helpers

#classify, #constantize, #decode, #encode

Instance Method Details

#add_hit(path, code, content_type) ⇒ Object



291
292
293
294
# File 'lib/rewritten.rb', line 291

def add_hit(path, code, content_type)
  h = {:path => path, :code => code, :content_type => content_type}
  Rewritten.redis.sadd("hits", encode(h) )
end

#add_translation(line, to) ⇒ Object

translations



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/rewritten.rb', line 138

def add_translation(line, to)
  from, flags = line.split(/\s+/)

  flags = flags.scan(/\[(\w+)\]/).first if flags

  redis.hset("from:#{from}", :to, to)
  redis.hset("from:#{from}", :flags, flags) if flags

  redis.sadd(:froms, from) 
  redis.sadd(:tos, to) 
  score = redis.zcard("to:#{to}") || 0
  redis.zadd("to:#{to}", score, from)  
end

#add_translations(to, froms) ⇒ Object



152
153
154
# File 'lib/rewritten.rb', line 152

def add_translations(to, froms)
  froms.each {|from|  add_translation(from, to)}
end

#after_fork(&block) ⇒ Object

The after_fork hook will be run in the child process and is passed the current job. Any changes you make, therefore, will only live as long as the job currently being processed.

Call with a block to set the hook. Call with no arguments to return the hook.



109
110
111
# File 'lib/rewritten.rb', line 109

def after_fork(&block)
  block ? (@after_fork = block) : @after_fork
end

#after_fork=(after_fork) ⇒ Object

Set the after_fork proc.



114
115
116
# File 'lib/rewritten.rb', line 114

def after_fork=(after_fork)
  @after_fork = after_fork
end

#all_fromsObject



182
183
184
# File 'lib/rewritten.rb', line 182

def all_froms
  Array(redis.smembers(:froms))
end

#all_hitsObject



296
297
298
# File 'lib/rewritten.rb', line 296

def all_hits
  Rewritten.redis.smembers("hits").map{|e| decode(e)}
end

#all_tosObject



186
187
188
# File 'lib/rewritten.rb', line 186

def all_tos
  Array(Rewritten.redis.smembers(:tos))
end

#appendix(some_from) ⇒ Object



261
262
263
264
265
# File 'lib/rewritten.rb', line 261

def appendix(some_from)
  base = base_from(some_from) || ''
  result = some_from.partition( base ).last
  result.chomp('/')
end

#base_from(some_from) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/rewritten.rb', line 247

def base_from(some_from)
  base_from = some_from.split('?')[0].chomp('/')
  if translate(some_from)
    some_from
  elsif translate(base_from)
    base_from
  elsif translate_partial? && base_from.count('/') > 1
    parts = base_from.split('/')
    base_from(parts.slice(0,parts.size-1).join('/'))
  else
    nil
  end
end

#before_first_fork(&block) ⇒ Object

The before_first_fork hook will be run in the parent process only once, before forking to run the first job. Be careful- any changes you make will be permanent for the lifespan of the worker.

Call with a block to set the hook. Call with no arguments to return the hook.



78
79
80
# File 'lib/rewritten.rb', line 78

def before_first_fork(&block)
  block ? (@before_first_fork = block) : @before_first_fork
end

#before_first_fork=(before_first_fork) ⇒ Object

Set a proc that will be called in the parent process before the worker forks for the first time.



84
85
86
# File 'lib/rewritten.rb', line 84

def before_first_fork=(before_first_fork)
  @before_first_fork = before_first_fork
end

#before_fork(&block) ⇒ Object

The before_fork hook will be run in the parent process before every job, so be careful- any changes you make will be permanent for the lifespan of the worker.

Call with a block to set the hook. Call with no arguments to return the hook.



94
95
96
# File 'lib/rewritten.rb', line 94

def before_fork(&block)
  block ? (@before_fork = block) : @before_fork
end

#before_fork=(before_fork) ⇒ Object

Set the before_fork proc.



99
100
101
# File 'lib/rewritten.rb', line 99

def before_fork=(before_fork)
  @before_fork = before_fork
end

#clear_translationsObject



173
174
175
# File 'lib/rewritten.rb', line 173

def clear_translations
  Rewritten.redis.del(*Rewritten.redis.keys) unless Rewritten.redis.keys.empty?
end

#exist_translation_for?(path) ⇒ Boolean

Returns:

  • (Boolean)


287
288
289
# File 'lib/rewritten.rb', line 287

def exist_translation_for?(path)
  get_current_translation(path) != path
end

#fromsObject

Returns an array of all known source URLs (that are to translated)



178
179
180
# File 'lib/rewritten.rb', line 178

def froms
  Array(redis.smembers(:froms))
end

#full_line(from) ⇒ Object



276
277
278
279
280
281
282
283
284
285
# File 'lib/rewritten.rb', line 276

def full_line(from)
  flags = get_flag_string(from)

  if flags == ""
    from
  else
    "#{from} [#{flags}]" 
  end

end

#get_all_translations(to) ⇒ Object



194
195
196
# File 'lib/rewritten.rb', line 194

def get_all_translations(to)
  Rewritten.redis.zrange("to:#{to}", 0, -1)
end

#get_current_translation(path, tail = nil) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/rewritten.rb', line 198

def get_current_translation(path, tail=nil)

  uri = URI.parse(path)

  # find directly
  translation = Rewritten.z_range("to:#{path}", -1)
 
  unless translation 
    translation = Rewritten.z_range("to:#{uri.path}", -1)
  end

  if translation.nil?
    if translate_partial? && path.count('/') > 1
      parts = path.split('/')
      shorter_path = parts.slice(0, parts.size-1).join('/')
      appendix = parts.last + (tail ? "/" + tail : "")
      return get_current_translation(shorter_path, appendix) 
    else
      return path
    end
  end

  complete_path = (tail ? translation+"/"+tail : translation)
  translated_uri = URI.parse(complete_path)
  uri.path = translated_uri.path
  uri.query = [translated_uri.query, uri.query].compact.join('&')
  uri.query = nil if uri.query == ''
  uri.to_s
end

#get_flag_string(from) ⇒ Object



267
268
269
# File 'lib/rewritten.rb', line 267

def get_flag_string(from)
  Rewritten.redis.hget("from:#{from}", :flags)||""
end

#has_flag?(from, c) ⇒ Boolean

Returns:

  • (Boolean)


271
272
273
274
# File 'lib/rewritten.rb', line 271

def has_flag?(from, c)
  return false unless Rewritten.redis.exists("from:#{from}")
  get_flag_string(from).index(c) != nil
end

#includes?(path) ⇒ Boolean

Returns:

  • (Boolean)


300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/rewritten.rb', line 300

def includes?(path)

  result = Rewritten.redis.hget("from:#{path.chomp('/')}", :to)
  result = Rewritten.redis.hget("from:#{path.split('?')[0]}", :to) unless result

  if result.nil? && translate_partial? && path.count('/') > 1
    parts = path.split('/')
    includes?( parts.slice(0,parts.size-1).join('/') )
  else
    result
  end

end

#infinitive(some_from) ⇒ Object

infinitive for translations only!



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/rewritten.rb', line 230

def infinitive(some_from)

  conjugated = some_from.chomp('/')

  to = translate(conjugated)
  to = translate(conjugated.split('?')[0]) unless to

  if to.nil? && translate_partial? && conjugated.count('/') > 1 
    parts = conjugated.split('/')
    shorter_path = parts.slice(0, parts.size-1).join('/')
    infinitive(shorter_path)
  else
    conjugated = get_current_translation(to) if to
    conjugated.split('?')[0].chomp('/')
  end
end

#infoObject

Returns a hash, similar to redis-rb’s #info, of interesting stats.



359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/rewritten.rb', line 359

def info
  return {
    :pending   => queues.inject(0) { |m,k| m + size(k) },
    #:processed => Stat[:processed],
    #:queues    => queues.size,
    #:workers   => workers.size.to_i,
    #:working   => working.size,
    #:failed    => Stat[:failed],
    :servers   => [redis_id],
    :environment  => ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
  }
end

#inline=(inline) ⇒ Object



130
131
132
# File 'lib/rewritten.rb', line 130

def inline=(inline)
  @inline = inline
end

#inline?Boolean Also known as: inline

If ‘inline’ is true Resque will call #perform method inline without queuing it into Redis and without any Resque callbacks. The ‘inline’ is false Resque jobs will be put in queue regularly.

Returns:

  • (Boolean)


125
126
127
# File 'lib/rewritten.rb', line 125

def inline?
  @inline
end

#keysObject

Returns an array of all known Resque keys in Redis. Redis’ KEYS operation is O(N) for the keyspace, so be careful - this can be slow for big databases.



374
375
376
377
378
# File 'lib/rewritten.rb', line 374

def keys
  redis.keys("*").map do |key|
    key.sub("#{redis.namespace}:", '')
  end
end

#num_fromsObject

return the number of froms



315
316
317
# File 'lib/rewritten.rb', line 315

def num_froms
  redis.scard(:froms).to_i
end

#num_translations(to) ⇒ Object



156
157
158
# File 'lib/rewritten.rb', line 156

def num_translations(to)
  Rewritten.redis.zcard("to:#{to}")
end

#per_pageObject



380
381
382
# File 'lib/rewritten.rb', line 380

def per_page
  20
end

#queuesObject

Returns an array of all known Resque queues as strings.



332
333
334
# File 'lib/rewritten.rb', line 332

def queues
  Array(redis.smembers(:queues))
end

#redisObject

Returns the current Redis connection. If none has been created, will create a new one.



54
55
56
57
58
# File 'lib/rewritten.rb', line 54

def redis
  return @redis if @redis
  self.redis = Redis.respond_to?(:connect) ? Redis.connect : "localhost:6379"
  self.redis
end

#redis=(server) ⇒ Object

Accepts:

1. A 'hostname:port' String
2. A 'hostname:port:db' String (to select the Redis db)
3. A 'hostname:port/namespace' String (to set the Redis namespace)
4. A Redis URL String 'redis://host:port'
5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`,
   or `Redis::Namespace`.


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rewritten.rb', line 23

def redis=(server)
  case server
  when String
    if server =~ /redis\:\/\//
      redis = Redis.connect(:url => server, :thread_safe => true)
    else
      server, namespace = server.split('/', 2)
      host, port, db = server.split(':')
      redis = Redis.new(:host => host, :port => port,
        :thread_safe => true, :db => db)
    end
    namespace ||= :rewritten

    @redis = Redis::Namespace.new(namespace, :redis => redis)
  when Redis::Namespace
    @redis = server
  else
    @redis = Redis::Namespace.new(:rewritten, :redis => server)
  end
end

#redis_idObject



60
61
62
63
64
65
66
67
68
69
# File 'lib/rewritten.rb', line 60

def redis_id
  # support 1.x versions of redis-rb
  if redis.respond_to?(:server)
    redis.server
  elsif redis.respond_to?(:nodes) # distributed
    redis.nodes.map { |n| n.id }.join(', ')
  else
    redis.client.id
  end
end

#remove_all_translations(to) ⇒ Object



167
168
169
170
171
# File 'lib/rewritten.rb', line 167

def remove_all_translations(to)
  get_all_translations(to).each do |from|
    Rewritten.remove_translation(from, to)
  end
end

#remove_queue(queue) ⇒ Object

Given a queue name, completely deletes the queue.



342
343
344
345
# File 'lib/rewritten.rb', line 342

def remove_queue(queue)
  redis.srem(:queues, queue.to_s)
  redis.del("queue:#{queue}")
end

#remove_translation(from, to) ⇒ Object



160
161
162
163
164
165
# File 'lib/rewritten.rb', line 160

def remove_translation(from, to)
   Rewritten.redis.del("from:#{from}")
   Rewritten.redis.srem(:froms, from)
   Rewritten.redis.zrem("to:#{to}", from)
   Rewritten.redis.srem(:tos, to) if num_translations(to) == 0
end

#targetsObject

Returns an array of all known URL targets.



337
338
339
# File 'lib/rewritten.rb', line 337

def targets 
  Array(redis.smembers(:targets))
end

#to_sObject



118
119
120
# File 'lib/rewritten.rb', line 118

def to_s
  "Rewritten Client connected to #{redis_id}"
end

#translate(from) ⇒ Object



190
191
192
# File 'lib/rewritten.rb', line 190

def translate(from)
  redis.hget("from:#{from}", :to)
end

#translate_partial=(yes_or_no) ⇒ Object



44
45
46
# File 'lib/rewritten.rb', line 44

def translate_partial=(yes_or_no)
  @translate_partial = yes_or_no
end

#translate_partial?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/rewritten.rb', line 48

def translate_partial?
  @translate_partial
end

#watch_queue(queue) ⇒ Object

Used internally to keep track of which queues we’ve created. Don’t call this directly.



349
350
351
# File 'lib/rewritten.rb', line 349

def watch_queue(queue)
  redis.sadd(:queues, queue.to_s)
end

#z_range(key, start = 0, count = 1) ⇒ Object

Does the dirty work of fetching a range of items from a Redis list and converting them into Ruby objects.



321
322
323
324
325
326
327
328
329
# File 'lib/rewritten.rb', line 321

def z_range(key, start = 0, count = 1)
  if count == 1
    redis.zrange(key, start, start)[0]
  else
    Array(redis.zrange(key, start, start+count-1)).map do |item|
      item
    end
  end
end