old_contents: """
  opbeat.contrib.django.middleware
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  :copyright: (c) 2011-2012 Opbeat
  
  Large portions are
  :copyright: (c) 2010 by the Sentry Team, see AUTHORS for more details.
  :license: BSD, see LICENSE for more details.
  """
  
  from __future__ import absolute_import
  from django.conf import settings
  from opbeat.contrib.django.models import client
  import threading
  import logging
  
  def _is_ignorable_404(uri):
      """
      Returns True if the given request *shouldn't* notify the site managers.
      """
      return any(pattern.search(uri) for pattern in settings.IGNORABLE_404_URLS)
  
  
  class Opbeat404CatchMiddleware(object):
      def process_response(self, request, response):
          if response.status_code != 404 or _is_ignorable_404(request.get_full_path()):
              return response
          data = client.get_data_from_request(request)
          data.update({
              'level': logging.INFO,
              'logger': 'http404',
          })
          result = client.capture('Message', param_message={'message':'Page Not Found: %s','params':[request.build_absolute_uri()]}, data=data)
          request.opbeat = {
              'app_id': data.get('app_id', client.app_id),
              'id': client.get_ident(result),
          }
          return response
  
  
  class OpbeatResponseErrorIdMiddleware(object):
      """
      Appends the X-Opbeat-ID response header for referencing a message within
      the Opbeat datastore.
      """
      def process_response(self, request, response):
          if not getattr(request, 'opbeat', None):
              return response
          response['X-Opbeat-ID'] = request.opbeat['id']
          return response
  
  
  class OpbeatLogMiddleware(object):
      # Create a threadlocal variable to store the session in for logging
      thread = threading.local()
  
      def process_request(self, request):
          self.thread.request = request
  
new_contents: """
  opbeat.contrib.django.middleware
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  :copyright: (c) 2011-2012 Opbeat
  
  Large portions are
  :copyright: (c) 2010 by the Sentry Team, see AUTHORS for more details.
  :license: BSD, see LICENSE for more details.
  """
  
  from __future__ import absolute_import
  from django.conf import settings
  from opbeat.contrib.django.models import client
  import threading
  import logging
  
  def _is_ignorable_404(uri):
      """
      Returns True if the given request *shouldn't* notify the site managers.
      """
      urls = getattr(settings, 'IGNORABLE_404_URLS', ())
      return any(pattern.search(uri) for pattern in urls)
  
  
  class Opbeat404CatchMiddleware(object):
      def process_response(self, request, response):
          if response.status_code != 404 or _is_ignorable_404(request.get_full_path()):
              return response
          data = client.get_data_from_request(request)
          data.update({
              'level': logging.INFO,
              'logger': 'http404',
          })
          result = client.capture('Message', param_message={'message':'Page Not Found: %s','params':[request.build_absolute_uri()]}, data=data)
          request.opbeat = {
              'app_id': data.get('app_id', client.app_id),
              'id': client.get_ident(result),
          }
          return response
  
  
  class OpbeatResponseErrorIdMiddleware(object):
      """
      Appends the X-Opbeat-ID response header for referencing a message within
      the Opbeat datastore.
      """
      def process_response(self, request, response):
          if not getattr(request, 'opbeat', None):
              return response
          response['X-Opbeat-ID'] = request.opbeat['id']
          return response
  
  
  class OpbeatLogMiddleware(object):
      # Create a threadlocal variable to store the session in for logging
      thread = threading.local()
  
      def process_request(self, request):
          self.thread.request = request
  
subject: Handle Django 1.3, which does not have a "IGNORABLE_404_URLS" setting by default