<commit_before>import Utils from './utils/utils';
import JSZip from 'jszip';

export class SceneBundle {

    constructor(url, path) {
        this.url = url;
        this.path = path || Utils.pathForURL(this.url);
    }

    load() {
        return Utils.loadResource(this.url);
    }

    urlFor(url) {
        return Utils.addBaseURL(url, this.path);
    }

}

export class ZipSceneBundle extends SceneBundle {

    constructor(url, path) {
        super(url, path);
        this.zip = null;
        this.files = {};
        this.urls = {};
        this.root = null;
    }

    load() {
        this.zip = new JSZip();

        if (typeof this.url === 'string') {
            return Utils.io(this.url, 60000, 'arraybuffer')
                .then(body => this.zip.loadAsync(body))
                .then(() => this.parseZipFiles())
                .then(() => this.loadRoot())
                .catch(e => Promise.reject(e));
        } else {
            return Promise.resolve(this);
        }
    }

    urlFor(url) {
        if (Utils.isRelativeURL(url)) {
            return this.urlForZipFile(url);
        }
        return Utils.addBaseURL(url, this.path);
    }

    loadRoot() {
        return this.findRoot()
            .then(() => Utils.loadResource(this.urlForZipFile(this.root)));
    }

    findRoot() {
        // Must be a single YAML at top level of zip
        let bundle_yaml = this.url.split('/').pop().split('.zip').shift() + '.yaml';
        let root = Object.keys(this.files)
            .filter(path => this.files[path].depth === 0)
            .filter(path => Utils.extensionForURL(path) === 'yaml');

        if (root.length === 1) {
            this.root = root[0];
        }
        else if (root.length > 1) {
            // check for name of bundle w/YAML extension
            let index = root.indexOf(bundle_yaml);
            if (index > -1) {
                this.root = root[index];
            }
        }

        if (!this.root) {
            let msg = `Could not find root scene for bundle '${this.url}': `;
            msg += `there must be either a single scene YAML file at the root level of the zip archive, `;
            msg += `or a scene YAML file with the same name as the archive file, e.g. '${bundle_yaml}'. `;
            if (root.length > 0) {
                msg += `Found these YAML files at the root level: ${root.map(r => '\'' + r + '\'' )}.`;
            }
            else {
                msg += `Found NO YAML files at the root level.`;
            }
            return Promise.reject(Error(msg));
        }
        return Promise.resolve();
    }

    parseZipFiles() {<commit_msg>zip bundles: update scene root logic to require single YAML, or explicit 'scene.yaml'<commit_after>import Utils from './utils/utils';
import JSZip from 'jszip';

export class SceneBundle {

    constructor(url, path) {
        this.url = url;
        this.path = path || Utils.pathForURL(this.url);
    }

    load() {
        return Utils.loadResource(this.url);
    }

    urlFor(url) {
        return Utils.addBaseURL(url, this.path);
    }

}

export class ZipSceneBundle extends SceneBundle {

    constructor(url, path) {
        super(url, path);
        this.zip = null;
        this.files = {};
        this.urls = {};
        this.root = null;
    }

    load() {
        this.zip = new JSZip();

        if (typeof this.url === 'string') {
            return Utils.io(this.url, 60000, 'arraybuffer')
                .then(body => this.zip.loadAsync(body))
                .then(() => this.parseZipFiles())
                .then(() => this.loadRoot())
                .catch(e => Promise.reject(e));
        } else {
            return Promise.resolve(this);
        }
    }

    urlFor(url) {
        if (Utils.isRelativeURL(url)) {
            return this.urlForZipFile(url);
        }
        return Utils.addBaseURL(url, this.path);
    }

    loadRoot() {
        return this.findRoot()
            .then(() => Utils.loadResource(this.urlForZipFile(this.root)));
    }

    findRoot() {
        // First check for explicit scene.yaml at zip root
        if (this.files['scene.yaml']) {
            this.root = 'scene.yaml';
        }

        // Second check for a single YAML at top level of zip
        let yamls = [];
        if (!this.root) {
            yamls = Object.keys(this.files)
                .filter(path => this.files[path].depth === 0)
                .filter(path => Utils.extensionForURL(path) === 'yaml');

            if (yamls.length === 1) {
                this.root = yamls[0];
            }
        }

        // No root found
        if (!this.root) {
            let msg = `Could not find root scene for bundle '${this.url}': `;
            msg += `The zip archive's root level must contain either a single scene YAML file, `;
            msg += `or a scene YAML file with name 'scene.yaml'. `;
            if (yamls.length > 0) {
                msg += `Found multiple YAML files at the root level but no 'scene.yaml': ${yamls.map(r => '\'' + r + '\'' )}.`;
            }
            else {
                msg += `Found NO YAML files at the root level.`;
            }
            return Promise.reject(Error(msg));
        }
        return Promise.resolve();
    }

    parseZipFiles() {
{'fraction_non_alphanumeric': 0.14082638362395755, 'fraction_numerical': 0.0037907505686125853, 'mean_word_length': 1.6437875751503006, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2182642', 'n_tokens_mistral': 1632, 'n_tokens_neox': 1549, 'n_words': 398}