text: # -*- coding: utf-8 -*-
  
  """Scrapy item loaders."""
  
  import json
  
  import jmespath
  
  from pytility import normalize_space
  from scrapy.loader import ItemLoader
  from scrapy.loader.processors import Identity, MapCompose, TakeFirst
  from scrapy.utils.misc import arg_to_iter
  from scrapy.utils.python import flatten
  
  from .items import ArticleItem, WebpageItem
  
  
  class JsonLoader(ItemLoader):
      """ enhance ItemLoader with JMESPath capabilities """
  
      def __init__(self, response=None, json_obj=None, **kwargs):
          response = response if hasattr(response, "text") else None
          super().__init__(response=response, **kwargs)
  
          if json_obj is None and response is not None:
              json_obj = json.loads(response.text)
  
          self.json_obj = json_obj
          self.context.setdefault("json", json_obj)
  
      def _get_jmes_values(self, jmes_paths):
          jmes_paths = arg_to_iter(jmes_paths)
          return flatten(
              jmespath.search(jmes_path, self.json_obj) for jmes_path in jmes_paths
          )
  
      def add_jmes(self, field_name, jmes, *processors, **kw):
          """ add values through JMESPath """
  
          values = self._get_jmes_values(jmes)
          self.add_value(field_name, values, *processors, **kw)
  
      def replace_jmes(self, field_name, jmes, *processors, **kw):
          """ replace values through JMESPath """
  
          values = self._get_jmes_values(jmes)
          self.replace_value(field_name, values, *processors, **kw)
  
      def get_jmes(self, jmes, *processors, **kw):
          """ get values through JMESPath """
  
          values = self._get_jmes_values(jmes)
          return self.get_value(values, *processors, **kw)
  
  
  class WebpageLoader(ItemLoader):
      """Webpage item loader."""
  
      default_item_class = WebpageItem
      default_input_processor = MapCompose(Identity(), str, normalize_space)
      default_output_processor = TakeFirst()
  
  
  class ArticleLoader(WebpageLoader):
      """Article item loader."""
  
      default_item_class = ArticleItem
  