<commit_before># All Content
# =======
#
# To prevent multiple copies of a model from floating around a single
# copy of all referenced content (loaded or not) is kept in this Collection
#
# This should be read-only by others
# New content models should be created by calling `ALL_CONTENT.add {}`

define [
  'jquery'
  'underscore'
  'backbone'
  'cs!collections/media-types'
  'cs!mixins/loadable'
], ($, _, Backbone, mediaTypes, loadableMixin) ->


  class EPUBContainer extends Backbone.Collection
    _loaded = $.Deferred()

    defaults:
      urlRoot: ''
    url: -> 'META-INF/container.xml'

    toJSON: -> model.toJSON() for model in @models

    # Extend the `load()` to wait until all content is loaded
    _loadComplex: (fetchPromise) ->
      promise = new $.Deferred()
      fetchPromise.done () =>
        contentPromises = @map (model) => model.load()
        $.when.apply($, contentPromises)
        .fail(() => alert 'problem loading book (OPF)')
        .done () =>
          promise.resolve(@)
      return promise

    parse: (json) ->
      # Github.read returns a `{sha: "1234", content: "<rootfiles>...</rootfiles>"}
      sha = json.sha
      xmlStr = json.content

      $xml = jQuery(xmlStr)
      ret = []
      $xml.find('rootfiles > rootfile').each (i, el) =>
        $el = jQuery(el)
        href = $el.attr 'full-path'
        mediaType = $el.attr 'media-type'
        ret.push {id: href, mediaType: mediaType}
      return ret


    model: (attrs, options) ->
      if attrs.mediaType
        Medium = mediaTypes.type(attrs.mediaType)
        # delete attrs.mediaType

        return new Medium(attrs)

      throw 'You must pass in the model or set its mediaType when adding to the content collection.'

    branches: () ->
      return _.where(@models, {branch: true})

    loading: () ->
      return _loaded.promise()

    # Save serially.
    save: (options) ->
      # save returns a promise.
      promise = new $.Deferred()

      # Pull the next model off the queue and save it.
      # When saving has completed, save the next model.
      saveNextItem = (queue) =>
        if not queue.length
          options?.success?()
          promise.resolve(@)
          return

        model = queue.shift()
        model.save()
        .fail((err) -> promise.reject(err))
        .done () -> saveNextItem(queue)

      # Save all the models that have changes
      changedModels = @filter (model) -> model.isDirty()
      saveNextItem(changedModels)
      return promise.promise()

  EPUBContainer = EPUBContainer.extend loadableMixin
  # All content in the Workspace
  return new EPUBContainer()
<commit_msg>Clean up load so error handlers fire when a file fails to load<commit_after># All Content
# =======
#
# To prevent multiple copies of a model from floating around a single
# copy of all referenced content (loaded or not) is kept in this Collection
#
# This should be read-only by others
# New content models should be created by calling `ALL_CONTENT.add {}`

define [
  'jquery'
  'underscore'
  'backbone'
  'cs!collections/media-types'
  'cs!mixins/loadable'
], ($, _, Backbone, mediaTypes, loadableMixin) ->


  class EPUBContainer extends Backbone.Collection
    _loaded = $.Deferred()

    defaults:
      urlRoot: ''
    url: -> 'META-INF/container.xml'

    toJSON: -> model.toJSON() for model in @models

    # Extend the `load()` to wait until all content is loaded
    _loadComplex: (fetchPromise) ->
      return fetchPromise.then () =>
        contentPromises = @map (model) => model.load()
        # Return a new promise that finishes once all the contentPromises have loaded
        return $.when.apply($, contentPromises)

    parse: (json) ->
      # Github.read returns a `{sha: "1234", content: "<rootfiles>...</rootfiles>"}
      sha = json.sha
      xmlStr = json.content

      $xml = jQuery(xmlStr)
      ret = []
      $xml.find('rootfiles > rootfile').each (i, el) =>
        $el = jQuery(el)
        href = $el.attr 'full-path'
        mediaType = $el.attr 'media-type'
        ret.push {id: href, mediaType: mediaType}
      return ret


    model: (attrs, options) ->
      if attrs.mediaType
        Medium = mediaTypes.type(attrs.mediaType)
        # delete attrs.mediaType

        return new Medium(attrs)

      throw 'You must pass in the model or set its mediaType when adding to the content collection.'

    branches: () ->
      return _.where(@models, {branch: true})

    loading: () ->
      return _loaded.promise()

    # Save serially.
    save: (options) ->
      # save returns a promise.
      promise = new $.Deferred()

      # Pull the next model off the queue and save it.
      # When saving has completed, save the next model.
      saveNextItem = (queue) =>
        if not queue.length
          options?.success?()
          promise.resolve(@)
          return

        model = queue.shift()
        model.save()
        .fail((err) -> promise.reject(err))
        .done () -> saveNextItem(queue)

      # Save all the models that have changes
      changedModels = @filter (model) -> model.isDirty()
      saveNextItem(changedModels)
      return promise.promise()

  EPUBContainer = EPUBContainer.extend loadableMixin
  # All content in the Workspace
  return new EPUBContainer()

{'fraction_non_alphanumeric': 0.1177584248390761, 'fraction_numerical': 0.0015145778114350624, 'mean_word_length': 2.4825313117996046, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, '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': '1982505', 'n_tokens_mistral': 1569, 'n_tokens_neox': 1531, 'n_words': 495}