parameters: (self, config, settings, target_folder)
docstring: Scan layers xml and see if there are external references.
  
          Find references to data outside data dir and include them in
          backup. Also, some references may point to specific url, which
          may not be available later.
docstring_summary: Scan layers xml and see if there are external references.
docstring_tokens: Scan layers xml and see if there are external references .
function: def dump_geoserver_externals(self, config, settings, target_folder):
          """Scan layers xml and see if there are external references.
  
          Find references to data outside data dir and include them in
          backup. Also, some references may point to specific url, which
          may not be available later.
          """
          external_folder = os.path.join(target_folder, utils.EXTERNAL_ROOT)
  
          def copy_external_resource(abspath):
              external_path = os.path.join(external_folder, abspath[1:])
              external_dir = os.path.dirname(external_path)
  
              if not os.path.isdir(external_dir):
                  os.makedirs(external_dir)
  
              try:
                  if not os.path.isdir(external_path) and os.path.exists(external_path):
                      shutil.copy2(abspath, external_path)
              except shutil.SameFileError:
                  logger.warning(f"WARNING: {abspath} and {external_path} are the same file!")
  
          def match_filename(key, text, regexp=re.compile("^(.+)$")):
              if key in ('filename', ):
                  match = regexp.match(text.decode("utf-8"))
                  if match:
                      relpath = match.group(1)
                      try:
                          abspath = relpath if os.path.isabs(relpath) else \
                              os.path.abspath(
                                  os.path.join(os.path.dirname(path), relpath))
                          if os.path.exists(abspath):
                              return abspath
                      except Exception:
                          logger.warning(f"WARNING: Error while trying to dump {text}")
                          return
  
          def match_fileurl(key, text, regexp=re.compile("^file:(.+)$")):
              if key in ('url', ):
                  match = regexp.match(text.decode("utf-8"))
                  if match:
                      relpath = match.group(1)
                      try:
                          abspath = relpath if os.path.isabs(relpath) else \
                              os.path.abspath(
                                  os.path.join(config.gs_data_dir, relpath))
                          if os.path.exists(abspath):
                              return abspath
                      except Exception:
                          logger.warning(f"WARNING: Error while trying to dump {text}")
                          return
  
          def dump_external_resources_from_xml(path):
  
              def find_external(tree, key=None):
                  if isinstance(tree, dict):
                      for key, value in tree.items():
                          for found in find_external(value, key=key):
                              yield found
                  elif isinstance(tree, list):
                      for item in tree:
                          for found in find_external(item, key=key):
                              yield found
                  elif isinstance(tree, str):
                      text = tree.encode('utf-8')
                      for find in (match_fileurl, match_filename):
                          found = find(key, text)
                          if found:
                              yield found
  
              with open(path, 'rb') as fd:
                  content = fd.read()
                  tree = parse_xml(content)
                  for found in find_external(tree):
                      if found.find(config.gs_data_dir) != 0:
                          copy_external_resource(found)
  
          def is_xml_file(filename, regexp=re.compile(".*.xml$")):
              return regexp.match(filename) is not None
  
          for directory in ('workspaces', 'styles'):
              source = os.path.join(config.gs_data_dir, directory)
              for root, dirs, files in os.walk(source):
                  for filename in filter(is_xml_file, files):
                      path = os.path.join(root, filename)
                      dump_external_resources_from_xml(path)
function_tokens: def dump_geoserver_externals ( self , config , settings , target_folder ) : external_folder = os . path . join ( target_folder , utils . EXTERNAL_ROOT ) def copy_external_resource ( abspath ) : external_path = os . path . join ( external_folder , abspath [ 1 : ] ) external_dir = os . path . dirname ( external_path ) if not os . path . isdir ( external_dir ) : os . makedirs ( external_dir ) try : if not os . path . isdir ( external_path ) and os . path . exists ( external_path ) : shutil . copy2 ( abspath , external_path ) except shutil . SameFileError : logger . warning ( f"WARNING: {abspath} and {external_path} are the same file!" ) def match_filename ( key , text , regexp = re . compile ( "^(.+)$" ) ) : if key in ( 'filename' , ) : match = regexp . match ( text . decode ( "utf-8" ) ) if match : relpath = match . group ( 1 ) try : abspath = relpath if os . path . isabs ( relpath ) else os . path . abspath ( os . path . join ( os . path . dirname ( path ) , relpath ) ) if os . path . exists ( abspath ) : return abspath except Exception : logger . warning ( f"WARNING: Error while trying to dump {text}" ) return def match_fileurl ( key , text , regexp = re . compile ( "^file:(.+)$" ) ) : if key in ( 'url' , ) : match = regexp . match ( text . decode ( "utf-8" ) ) if match : relpath = match . group ( 1 ) try : abspath = relpath if os . path . isabs ( relpath ) else os . path . abspath ( os . path . join ( config . gs_data_dir , relpath ) ) if os . path . exists ( abspath ) : return abspath except Exception : logger . warning ( f"WARNING: Error while trying to dump {text}" ) return def dump_external_resources_from_xml ( path ) : def find_external ( tree , key = None ) : if isinstance ( tree , dict ) : for key , value in tree . items ( ) : for found in find_external ( value , key = key ) : yield found elif isinstance ( tree , list ) : for item in tree : for found in find_external ( item , key = key ) : yield found elif isinstance ( tree , str ) : text = tree . encode ( 'utf-8' ) for find in ( match_fileurl , match_filename ) : found = find ( key , text ) if found : yield found with open ( path , 'rb' ) as fd : content = fd . read ( ) tree = parse_xml ( content ) for found in find_external ( tree ) : if found . find ( config . gs_data_dir ) != 0 : copy_external_resource ( found ) def is_xml_file ( filename , regexp = re . compile ( ".*.xml$" ) ) : return regexp . match ( filename ) is not None for directory in ( 'workspaces' , 'styles' ) : source = os . path . join ( config . gs_data_dir , directory ) for root , dirs , files in os . walk ( source ) : for filename in filter ( is_xml_file , files ) : path = os . path . join ( root , filename ) dump_external_resources_from_xml ( path )