loadPlayMetadata function

PlayMetadata loadPlayMetadata(
  1. String path
)

Loads the Play metadata tree at path.

Throws MetadataException — shared with the App Store side, because a caller checking both wants one exception type and one message style.

Implementation

PlayMetadata loadPlayMetadata(String path) {
  final root = Directory(path);
  if (!root.existsSync()) {
    throw MetadataException('$path does not exist');
  }

  final metadata = PlayMetadata(path);

  final defaultLanguage = File('$path/details/default_language.txt');
  if (defaultLanguage.existsSync()) {
    final value = defaultLanguage.readAsStringSync().trim();
    metadata.defaultLanguage = value.isEmpty ? null : value;
  }

  final listings = Directory('$path/listings');
  if (!listings.existsSync()) {
    throw MetadataException(
      '$path has no listings/ directory — a Play tree keeps each locale in '
      'listings/<bcp-47>/',
    );
  }

  final localeDirs = listings.listSync().whereType<Directory>().toList()
    ..sort((a, b) => a.path.compareTo(b.path));

  for (final dir in localeDirs) {
    final locale = dir.path.split(Platform.pathSeparator).last;
    final entry = PlayLocaleMetadata(locale);

    for (final field in playListingLimits.keys) {
      final file = File('${dir.path}/$field.txt');
      if (file.existsSync()) {
        // Trailing newline removed and nothing else: a text file ends with one
        // and Play does not store it, but stripping any further would be the
        // normalisation this file's header warns about.
        entry.text[field] = _withoutTrailingNewline(file.readAsStringSync());
      }
    }

    final images = Directory('${dir.path}/images');
    if (images.existsSync()) {
      final imageDirs = images.listSync().whereType<Directory>().toList()
        ..sort((a, b) => a.path.compareTo(b.path));
      for (final imageDir in imageDirs) {
        final name = imageDir.path.split(Platform.pathSeparator).last;
        final files =
            imageDir
                .listSync()
                .whereType<File>()
                .where((f) => _isImage(f.path))
                .toList()
              ..sort((a, b) => a.path.compareTo(b.path));
        entry.images[name] = files;
      }
    }

    metadata.locales.add(entry);
  }

  return metadata;
}