parameters: (
      source, destination, debug, verbose, quiet, force, config, theme, title, ncpu
  )
docstring: Run sigal to process a directory.
  
      If provided, 'source', 'destination' and 'theme' will override the
      corresponding values from the settings file.
docstring_summary: Run sigal to process a directory.
docstring_tokens: Run sigal to process a directory .
function: def build(
      source, destination, debug, verbose, quiet, force, config, theme, title, ncpu
  ):
      """Run sigal to process a directory.
  
      If provided, 'source', 'destination' and 'theme' will override the
      corresponding values from the settings file.
  
      """
      if sum([debug, verbose, quiet]) > 1:
          sys.exit('Only one option of debug, verbose and quiet should be used')
  
      if debug:
          level = logging.DEBUG
      elif verbose:
          level = logging.INFO
      elif quiet:
          level = logging.ERROR
      else:
          level = logging.WARNING
  
      init_logging(__name__, level=level)
      logger = logging.getLogger(__name__)
  
      if not os.path.isfile(config):
          logger.error("Settings file not found: %s", config)
          sys.exit(1)
  
      start_time = time.time()
      settings = read_settings(config)
  
      for key in ('source', 'destination', 'theme'):
          arg = locals()[key]
          if arg is not None:
              settings[key] = os.path.abspath(arg)
          logger.info("%12s : %s", key.capitalize(), settings[key])
  
      if not settings['source'] or not os.path.isdir(settings['source']):
          logger.error("Input directory not found: %s", settings['source'])
          sys.exit(1)
  
      # on windows os.path.relpath raises a ValueError if the two paths are on
      # different drives, in that case we just ignore the exception as the two
      # paths are anyway not relative
      relative_check = True
      try:
          relative_check = os.path.relpath(
              settings['destination'], settings['source']
          ).startswith('..')
      except ValueError:
          pass
  
      if not relative_check:
          logger.error("Output directory should be outside of the input directory.")
          sys.exit(1)
  
      if title:
          settings['title'] = title
  
      locale.setlocale(locale.LC_ALL, settings['locale'])
      init_plugins(settings)
  
      gal = Gallery(settings, ncpu=ncpu, quiet=quiet)
      gal.build(force=force)
  
      # copy extra files
      for src, dst in settings['files_to_copy']:
          src = os.path.join(settings['source'], src)
          dst = os.path.join(settings['destination'], dst)
          logger.debug('Copy %s to %s', src, dst)
          copy(src, dst, symlink=settings['orig_link'], rellink=settings['rel_link'])
  
      stats = gal.stats
  
      def format_stats(_type):
          opt = [
              "{} {}".format(stats[_type + '_' + subtype], subtype)
              for subtype in ('skipped', 'failed')
              if stats[_type + '_' + subtype] > 0
          ]
          opt = ' ({})'.format(', '.join(opt)) if opt else ''
          return f'{stats[_type]} {_type}s{opt}'
  
      if not quiet:
          stats_str = ''
          types = sorted({t.rsplit('_', 1)[0] for t in stats})
          for t in types[:-1]:
              stats_str += f'{format_stats(t)} and '
          stats_str += f'{format_stats(types[-1])}'
          end_time = time.time() - start_time
          print(f'Done, processed {stats_str} in {end_time:.2f} seconds.')
function_tokens: def build ( source , destination , debug , verbose , quiet , force , config , theme , title , ncpu ) : if sum ( [ debug , verbose , quiet ] ) > 1 : sys . exit ( 'Only one option of debug, verbose and quiet should be used' ) if debug : level = logging . DEBUG elif verbose : level = logging . INFO elif quiet : level = logging . ERROR else : level = logging . WARNING init_logging ( __name__ , level = level ) logger = logging . getLogger ( __name__ ) if not os . path . isfile ( config ) : logger . error ( "Settings file not found: %s" , config ) sys . exit ( 1 ) start_time = time . time ( ) settings = read_settings ( config ) for key in ( 'source' , 'destination' , 'theme' ) : arg = locals ( ) [ key ] if arg is not None : settings [ key ] = os . path . abspath ( arg ) logger . info ( "%12s : %s" , key . capitalize ( ) , settings [ key ] ) if not settings [ 'source' ] or not os . path . isdir ( settings [ 'source' ] ) : logger . error ( "Input directory not found: %s" , settings [ 'source' ] ) sys . exit ( 1 ) # on windows os.path.relpath raises a ValueError if the two paths are on # different drives, in that case we just ignore the exception as the two # paths are anyway not relative relative_check = True try : relative_check = os . path . relpath ( settings [ 'destination' ] , settings [ 'source' ] ) . startswith ( '..' ) except ValueError : pass if not relative_check : logger . error ( "Output directory should be outside of the input directory." ) sys . exit ( 1 ) if title : settings [ 'title' ] = title locale . setlocale ( locale . LC_ALL , settings [ 'locale' ] ) init_plugins ( settings ) gal = Gallery ( settings , ncpu = ncpu , quiet = quiet ) gal . build ( force = force ) # copy extra files for src , dst in settings [ 'files_to_copy' ] : src = os . path . join ( settings [ 'source' ] , src ) dst = os . path . join ( settings [ 'destination' ] , dst ) logger . debug ( 'Copy %s to %s' , src , dst ) copy ( src , dst , symlink = settings [ 'orig_link' ] , rellink = settings [ 'rel_link' ] ) stats = gal . stats def format_stats ( _type ) : opt = [ "{} {}" . format ( stats [ _type + '_' + subtype ] , subtype ) for subtype in ( 'skipped' , 'failed' ) if stats [ _type + '_' + subtype ] > 0 ] opt = ' ({})' . format ( ', ' . join ( opt ) ) if opt else '' return f'{stats[_type]} {_type}s{opt}' if not quiet : stats_str = '' types = sorted ( { t . rsplit ( '_' , 1 ) [ 0 ] for t in stats } ) for t in types [ : - 1 ] : stats_str += f'{format_stats(t)} and ' stats_str += f'{format_stats(types[-1])}' end_time = time . time ( ) - start_time print ( f'Done, processed {stats_str} in {end_time:.2f} seconds.' )