docs: def run(self, args):
          """
          Main entry point of script
          """
          logging.basicConfig(stream=sys.stdout, level=logging.INFO)
          configuration = self.configuration
          configuration.locale_dir.parent.makedirs_p()
          # pylint: disable=attribute-defined-outside-init
          self.source_msgs_dir = configuration.source_messages_dir
  
          # The extraction process clobbers django.po and djangojs.po.
          # Save them so that it won't do that.
          self.rename_source_file('django.po', 'django-saved.po')
          self.rename_source_file('djangojs.po', 'djangojs-saved.po')
  
          # Extract strings from mako templates.
          verbosity_map = {
              0: "-q",
              1: "",
              2: "-v",
          }
          babel_verbosity = verbosity_map.get(args.verbose, "")
  
          if args.verbose:
              stderr = None
          else:
              stderr = DEVNULL
  
          # --keyword informs Babel that `interpolate()` is an expected
          # gettext function, which is necessary because the `tokenize` function
          # in the `markey` module marks it as such and passes it to Babel.
          # (These functions are called in the django-babel-underscore module.)
          babel_cmd_template = (
              'pybabel {verbosity} extract --mapping={config} '
              '--add-comments="Translators:" --keyword="interpolate" '
              '. --output={output}'
          )
  
          babel_mako_cfg = self.base(configuration.locale_dir, 'babel_mako.cfg')
          if babel_mako_cfg.exists():
              babel_mako_cmd = babel_cmd_template.format(
                  verbosity=babel_verbosity,
                  config=babel_mako_cfg,
                  output=self.base(configuration.source_messages_dir, 'mako.po'),
              )
  
              execute(babel_mako_cmd, working_directory=configuration.root_dir, stderr=stderr)
  
          babel_underscore_cfg = self.base(configuration.locale_dir, 'babel_underscore.cfg')
          if babel_underscore_cfg.exists():
              babel_underscore_cmd = babel_cmd_template.format(
                  verbosity=babel_verbosity,
                  config=babel_underscore_cfg,
                  output=self.base(configuration.source_messages_dir, 'underscore.po'),
              )
  
              execute(babel_underscore_cmd, working_directory=configuration.root_dir, stderr=stderr)
  
          makemessages = "django-admin.py makemessages -l en -v{}".format(args.verbose)
          ignores = " ".join('--ignore="{}/*"'.format(d) for d in configuration.ignore_dirs)
          if ignores:
              makemessages += " " + ignores
  
          # Extract strings from django source files (*.py, *.html, *.txt).
          make_django_cmd = makemessages + ' -d django'
          execute(make_django_cmd, working_directory=configuration.root_dir, stderr=stderr)
  
          # Extract strings from Javascript source files (*.js, *jsx).
          make_djangojs_cmd = makemessages + ' -d djangojs -e js,jsx'
          execute(make_djangojs_cmd, working_directory=configuration.root_dir, stderr=stderr)
  
          # makemessages creates 'django.po'. This filename is hardcoded.
          # Rename it to django-partial.po to enable merging into django.po later.
          self.rename_source_file('django.po', 'django-partial.po')
  
          # makemessages creates 'djangojs.po'. This filename is hardcoded.
          # Rename it to djangojs-partial.po to enable merging into djangojs.po later.
          self.rename_source_file('djangojs.po', 'djangojs-partial.po')
  
          files_to_clean = set()
  
          # Extract strings from third-party applications.
          for app_name in configuration.third_party:
              # Import the app to find out where it is.  Then use pybabel to extract
              # from that directory.
              app_module = importlib.import_module(app_name)
              app_dir = Path(app_module.__file__).dirname().dirname()  # pylint: disable=no-value-for-parameter
              output_file = self.source_msgs_dir / (app_name + ".po")
              files_to_clean.add(output_file)
  
              babel_cmd = 'pybabel {verbosity} extract -F {config} -c "Translators:" {app} -o {output}'
              babel_cmd = babel_cmd.format(
                  verbosity=babel_verbosity,
                  config=configuration.locale_dir / 'babel_third_party.cfg',
                  app=app_name,
                  output=output_file,
              )
              execute(babel_cmd, working_directory=app_dir, stderr=stderr)
  
          # Segment the generated files.
          segmented_files = segment_pofiles(configuration, configuration.source_locale)
          files_to_clean.update(segmented_files)
  
          # Finish each file.
          for filename in files_to_clean:
              LOG.info('Cleaning %s', filename)
              pofile = polib.pofile(self.source_msgs_dir.joinpath(filename))
              # replace default headers with edX headers
              fix_header(pofile)
              # replace default metadata with edX metadata
              fix_metadata(pofile)
              # remove key strings which belong in messages.po
              strip_key_strings(pofile)
              pofile.save()
  
          # Restore the saved .po files.
          self.rename_source_file('django-saved.po', 'django.po')
          self.rename_source_file('djangojs-saved.po', 'djangojs.po')