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

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#classify, #constantize, #decode, #encode

Instance Attribute Details

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



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

def after_fork(&block)
  block ? (@after_fork = block) : @after_fork
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.



72
73
74
# File 'lib/rewritten.rb', line 72

def before_first_fork(&block)
  block ? (@before_first_fork = block) : @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.



86
87
88
# File 'lib/rewritten.rb', line 86

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

#inline=(value) ⇒ Object

Sets the attribute inline

Parameters:

  • value

    the value to set the attribute inline to.



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

def inline=(value)
  @inline = value
end

#translate_partialObject

Returns the value of attribute translate_partial.



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

def translate_partial
  @translate_partial
end

Instance Method Details

#add_hit(path, code, content_type) ⇒ Object



273
274
275
276
# File 'lib/rewritten.rb', line 273

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



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rewritten.rb', line 124

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



138
139
140
# File 'lib/rewritten.rb', line 138

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

#all_fromsObject



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

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

#all_hitsObject



278
279
280
# File 'lib/rewritten.rb', line 278

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

#all_tosObject



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

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

#appendix(some_from) ⇒ Object



243
244
245
246
247
248
# File 'lib/rewritten.rb', line 243

def appendix(some_from)
  base = base_from(some_from) || ''
  result = some_from.partition(base).last
  return '' if result == ''
  result.split('?').first.chomp('/')
end

#base_from(some_from) ⇒ Object



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

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('/'))
      end
end

#clear_translationsObject



159
160
161
# File 'lib/rewritten.rb', line 159

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

#exist_translation_for?(path) ⇒ Boolean

Returns:

  • (Boolean)


269
270
271
# File 'lib/rewritten.rb', line 269

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

#flag?(from, c) ⇒ Boolean

Returns:

  • (Boolean)


254
255
256
257
# File 'lib/rewritten.rb', line 254

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

#fromsObject

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



164
165
166
# File 'lib/rewritten.rb', line 164

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

#full_line(from) ⇒ Object



259
260
261
262
263
264
265
266
267
# File 'lib/rewritten.rb', line 259

def full_line(from)
  flags = get_flag_string(from)

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

#get_all_translations(to) ⇒ Object



180
181
182
# File 'lib/rewritten.rb', line 180

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

#get_current_translation(path, tail = nil) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/rewritten.rb', line 184

def get_current_translation(path, tail = nil)
  uri = URI.parse(path)

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

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

  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



250
251
252
# File 'lib/rewritten.rb', line 250

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

#includes?(path) ⇒ Boolean

Returns:

  • (Boolean)


282
283
284
285
286
287
288
289
290
291
292
# File 'lib/rewritten.rb', line 282

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!



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/rewritten.rb', line 212

def infinitive(some_from)
  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 = conjugated.split('?')[0] || ''
    conjugated.chomp('/')
  end
end

#infoObject

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



338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/rewritten.rb', line 338

def info
  {
    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?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)


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

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.



353
354
355
356
357
# File 'lib/rewritten.rb', line 353

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

#num_fromsObject

return the number of froms



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

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

#num_translations(to) ⇒ Object



142
143
144
# File 'lib/rewritten.rb', line 142

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

#per_pageObject



359
360
361
# File 'lib/rewritten.rb', line 359

def per_page
  20
end

#queuesObject

Returns an array of all known Resque queues as strings.



312
313
314
# File 'lib/rewritten.rb', line 312

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

#redisObject

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



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

def redis
  return @redis if @redis
  self.redis = Redis.respond_to?(:connect) ? Redis.connect : 'localhost:6379'
  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



54
55
56
57
58
59
60
61
62
63
# File 'lib/rewritten.rb', line 54

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(&:id).join(', ')
  else
    redis.client.id
  end
end

#remove_all_translations(to) ⇒ Object



153
154
155
156
157
# File 'lib/rewritten.rb', line 153

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.



322
323
324
325
# File 'lib/rewritten.rb', line 322

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

#remove_translation(from, to) ⇒ Object



146
147
148
149
150
151
# File 'lib/rewritten.rb', line 146

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.



317
318
319
# File 'lib/rewritten.rb', line 317

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

#to_sObject



106
107
108
# File 'lib/rewritten.rb', line 106

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

#translate(from) ⇒ Object



176
177
178
# File 'lib/rewritten.rb', line 176

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

#watch_queue(queue) ⇒ Object

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



329
330
331
# File 'lib/rewritten.rb', line 329

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.



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

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