|  | @@ -14,7 +14,7 @@ import socket
 | 
	
		
			
				|  |  |  from functools import partial
 | 
	
		
			
				|  |  |  from itertools import cycle, islice
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -from kombu import eventloop
 | 
	
		
			
				|  |  | +from kombu import eventloop, Queue
 | 
	
		
			
				|  |  |  from kombu.exceptions import StdChannelError
 | 
	
		
			
				|  |  |  from kombu.utils.encoding import ensure_bytes
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -98,13 +98,13 @@ def migrate_tasks(source, dest, migrate=migrate_task, app=None,
 | 
	
		
			
				|  |  |                          on_declare_queue=on_declare_queue, **kwargs)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -def move_tasks(conn, predicate, exchange, routing_key, app=None, **kwargs):
 | 
	
		
			
				|  |  | +def move(predicate, conn, exchange=None, routing_key=None, app=None, **kwargs):
 | 
	
		
			
				|  |  |      """Find tasks by filtering them and move the tasks to a new queue.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    :param conn: Connection to use.
 | 
	
		
			
				|  |  |      :param predicate: Filter function with signature ``(body, message)``.
 | 
	
		
			
				|  |  | -    :param exchange: Destination exchange.
 | 
	
		
			
				|  |  | -    :param routing_key: Destination routing key.
 | 
	
		
			
				|  |  | +    :param conn: Connection to use.
 | 
	
		
			
				|  |  | +    :keyword exchange: Default destination exchange.
 | 
	
		
			
				|  |  | +    :keyword routing_key: Default destination routing key.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      Also supports the same keyword arguments as :func:`start_filter`.
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -117,21 +117,54 @@ def move_tasks(conn, predicate, exchange, routing_key, app=None, **kwargs):
 | 
	
		
			
				|  |  |              if body['id'] == wanted_id:
 | 
	
		
			
				|  |  |                  return True
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        move_tasks(conn, is_wanted_task, exchange, routing_key)
 | 
	
		
			
				|  |  | +        move(is_wanted_task, conn, exchange, routing_key)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    The predicate may also return a tuple of ``(exchange, routing_key)``
 | 
	
		
			
				|  |  | +    to specify the destination to where the task should be moved,
 | 
	
		
			
				|  |  | +    or a :class:`~kombu.entitiy.Queue` instance.
 | 
	
		
			
				|  |  | +    Any other true value means that the task will be moved to the
 | 
	
		
			
				|  |  | +    default exchange/routing_key.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      """
 | 
	
		
			
				|  |  |      app = app_or_default(app)
 | 
	
		
			
				|  |  |      producer = app.amqp.TaskProducer(conn)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def on_task(body, message):
 | 
	
		
			
				|  |  | -        if predicate(body, message):
 | 
	
		
			
				|  |  | +        ret = predicate(body, message)
 | 
	
		
			
				|  |  | +        if ret:
 | 
	
		
			
				|  |  | +            if isinstance(ret, Queue):
 | 
	
		
			
				|  |  | +                ex, rk = ret.exchange.name, ret.routing_key
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                ex, rk = expand_dest(ret, exchange, routing_key)
 | 
	
		
			
				|  |  |              republish(producer, message,
 | 
	
		
			
				|  |  | -                      exchange=exchange, routing_key=routing_key)
 | 
	
		
			
				|  |  | +                      exchange=ex, routing_key=rk)
 | 
	
		
			
				|  |  |              message.ack()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      return start_filter(app, conn, on_task, **kwargs)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +def expand_dest(ret, exchange, routing_key):
 | 
	
		
			
				|  |  | +    try:
 | 
	
		
			
				|  |  | +        ex, rk = ret
 | 
	
		
			
				|  |  | +    except (TypeError, ValueError):
 | 
	
		
			
				|  |  | +        ex, rk = exchange, routing_key
 | 
	
		
			
				|  |  | +    return ex, rk
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +# XXX Deprecated (arguments rearranged)
 | 
	
		
			
				|  |  | +move_tasks = lambda conn, pred, *a, **kw: move(pred, conn, *a, **kw)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +def task_id_eq(task_id, body, message):
 | 
	
		
			
				|  |  | +    return body['id'] == task_id
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +def task_id_in(ids, body, message):
 | 
	
		
			
				|  |  | +    return body['id'] in ids
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  def move_task_by_id(conn, task_id, exchange, routing_key, **kwargs):
 | 
	
		
			
				|  |  |      """Find a task by id and move it to another queue.
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -143,11 +176,8 @@ def move_task_by_id(conn, task_id, exchange, routing_key, **kwargs):
 | 
	
		
			
				|  |  |      Also supports the same keyword arguments as :func:`start_filter`.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      """
 | 
	
		
			
				|  |  | -    def predicate(body, message):
 | 
	
		
			
				|  |  | -        if body['id'] == task_id:
 | 
	
		
			
				|  |  | -            return True
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    return move_tasks(conn, predicate, exchange, routing_key, **kwargs)
 | 
	
		
			
				|  |  | +    return move(conn, partial(task_id_eq, task_id),
 | 
	
		
			
				|  |  | +                exchange, routing_key, **kwargs)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  def prepare_queues(queues):
 | 
	
	
		
			
				|  | @@ -163,7 +193,8 @@ def prepare_queues(queues):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  def start_filter(app, conn, filter, limit=None, timeout=1.0,
 | 
	
		
			
				|  |  |          ack_messages=False, migrate=migrate_task, tasks=None, queues=None,
 | 
	
		
			
				|  |  | -        callback=None, forever=False, on_declare_queue=None, **kwargs):
 | 
	
		
			
				|  |  | +        callback=None, forever=False, on_declare_queue=None,
 | 
	
		
			
				|  |  | +        consume_from=None, **kwargs):
 | 
	
		
			
				|  |  |      state = State()
 | 
	
		
			
				|  |  |      queues = prepare_queues(queues)
 | 
	
		
			
				|  |  |      if isinstance(tasks, basestring):
 | 
	
	
		
			
				|  | @@ -177,7 +208,7 @@ def start_filter(app, conn, filter, limit=None, timeout=1.0,
 | 
	
		
			
				|  |  |      def ack_message(body, message):
 | 
	
		
			
				|  |  |          message.ack()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    consumer = app.amqp.TaskConsumer(conn)
 | 
	
		
			
				|  |  | +    consumer = app.amqp.TaskConsumer(conn, queues=consume_from)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      if tasks:
 | 
	
		
			
				|  |  |          filter = filter_callback(filter, tasks)
 |