Step 1 in converting to a Backbone-based website
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
###
|
||||
# crafting_guide - base_model.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class BaseModel extends Backbone.Model
|
||||
|
||||
constructor: (attributes={}, options={})->
|
||||
super attributes, options
|
||||
|
||||
makeGetter = (name)-> return -> @get name
|
||||
makeSetter = (name)-> return (value)-> @set name, value
|
||||
for name in _.keys attributes
|
||||
continue if name is 'id'
|
||||
Object.defineProperty this, name, get:makeGetter(name), set:makeSetter(name)
|
||||
|
||||
# Backbone.Model Overrides #####################################################################
|
||||
|
||||
sync: -> # do nothing
|
||||
|
||||
# Object Overrides #############################################################################
|
||||
|
||||
toString: ->
|
||||
return "#{@constructor.name} (#{@cid})"
|
||||
@@ -0,0 +1,19 @@
|
||||
###
|
||||
# Crafting Guide - item.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
BaseModel = require './base_model'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class Item extends BaseModel
|
||||
|
||||
constructor: (attributes={}, options={})->
|
||||
attributes.name ?= ''
|
||||
attributes.quantity ?= 1
|
||||
super attributes, options
|
||||
|
||||
# Public Methods ###############################################################################
|
||||
@@ -0,0 +1,17 @@
|
||||
###
|
||||
# Crafting Guide - landing_page.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
BaseModel = require './base_model'
|
||||
RecipeCatalog = require './recipe_catalog'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class LandingPage extends BaseModel
|
||||
|
||||
constructor: (attributes={}, options={})->
|
||||
attributes.catalog ?= new RecipeCatalog
|
||||
super attributes, options
|
||||
@@ -0,0 +1,81 @@
|
||||
###
|
||||
# Crafting Guide - v1.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
Item = require '../item'
|
||||
Recipe = require '../recipe'
|
||||
RecipeBook = require '../recipe_book'
|
||||
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class V1
|
||||
|
||||
constructor: ->
|
||||
@_errorLocation = 'the header information'
|
||||
|
||||
parse: (data)->
|
||||
return @_parseRecipeBook data
|
||||
|
||||
# Private Methods ##############################################################################
|
||||
|
||||
_parseRecipeBook: (data)->
|
||||
if not data? then throw new Error 'recipe book data is missing'
|
||||
if not data.version? then throw new Error 'version is required'
|
||||
if not data.mod_name? then throw new Error 'mod_name is required'
|
||||
if not data.mod_version? then throw new Error 'mod_version is required'
|
||||
if not _.isArray(data.recipes) then throw new Error 'recipes must be an array'
|
||||
|
||||
book = new RecipeBook version:data.version, modName:data.mod_name, modVersion:data.mod_version
|
||||
book.description = data.description or ''
|
||||
|
||||
for index in [0...data.recipes.length]
|
||||
@_errorLocation = "recipe #{index + 1}"
|
||||
recipeData = data.recipes[index]
|
||||
book.recipes.push @_parseRecipe recipeData
|
||||
|
||||
return book
|
||||
|
||||
_parseRecipe: (data, options={})->
|
||||
if not data? then throw new Error "recipe data is missing for #{@_errorLocation}"
|
||||
if not data.output? then throw new Error "#{@_errorLocation} is missing output"
|
||||
if not data.input? then throw new Error "#{@_errorLocation} is missing input"
|
||||
|
||||
output = @_parseItemList data.output, field:'output', canBeEmpty:false
|
||||
@_errorLocation = "recipe for output[0].name"
|
||||
|
||||
data.tools ?= []
|
||||
input = @_parseItemList data.input, field:'input', canBeEmpty:false
|
||||
tools = @_parseItemList data.tools, field:'tools', canBeEmpty:true
|
||||
|
||||
return new Recipe input:input, output:output, tools:tools
|
||||
|
||||
_parseItemList: (data, options={})->
|
||||
if not data? then throw new Error "#{@_errorLocation} must have an #{options.field} field"
|
||||
|
||||
if not _.isArray(data) then data = [data]
|
||||
if data.length is 0 and not options.canBeEmpty
|
||||
throw new Error "#{options.field} for #{@_errorLocation} cannot be empty"
|
||||
|
||||
result = []
|
||||
for index in [0...data.length]
|
||||
itemData = data[index]
|
||||
result.push @_parseItem itemData, field:options.field, index:index
|
||||
|
||||
return result
|
||||
|
||||
_parseItem: (data, options={})->
|
||||
errorBase = "#{options.field} element #{options.index} for #{@_errorLocation}"
|
||||
if not data? then throw new Error "#{errorBase} is missing"
|
||||
|
||||
if _.isString(data) then data = [1, data]
|
||||
if not _.isArray(data) then throw new Error "#{errorBase} must be an array"
|
||||
|
||||
if data.length is 1 then data.unshift 1
|
||||
if data.length isnt 2 then throw new Error "#{errorBase} must have at least one element"
|
||||
if not _.isNumber(data[0]) then throw new Error "#{errorBase} must start with a number"
|
||||
|
||||
return new Item quantity:data[0], name:data[1]
|
||||
@@ -0,0 +1,17 @@
|
||||
###
|
||||
# Crafting Guide - recipe.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
BaseModel = require './base_model'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class Recipe extends BaseModel
|
||||
|
||||
constructor: (attributes={}, options={})->
|
||||
super attributes, options
|
||||
|
||||
Object.defineProperty this, 'name', get:-> @output[0].name
|
||||
@@ -0,0 +1,38 @@
|
||||
###
|
||||
# Crafting Guide - recipe_book.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
BaseModel = require './base_model'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class RecipeBook extends BaseModel
|
||||
|
||||
constructor: (attributes={}, options={})->
|
||||
if _.isEmpty(attributes.modName) then throw new Error 'modName cannot be empty'
|
||||
if _.isEmpty(attributes.modVersion) then throw new Error 'modVersion cannot be empty'
|
||||
|
||||
attributes.description ?= ''
|
||||
attributes.recipes ?= []
|
||||
super attributes, options
|
||||
|
||||
# Public Methods ###############################################################################
|
||||
|
||||
getRecipes: (name)->
|
||||
result = []
|
||||
for recipe in @recipes
|
||||
if recipe.name is name
|
||||
result.push recipe
|
||||
|
||||
return result
|
||||
|
||||
# Object Overrides #############################################################################
|
||||
|
||||
toString: ->
|
||||
return "RecipeBook (#{@cid}) {
|
||||
modName:#{@modName},
|
||||
modVersion:#{@modVersion},
|
||||
recipes:#{@recipes.length} items}"
|
||||
@@ -0,0 +1,26 @@
|
||||
###
|
||||
# Crafting Guide - recipe_book_parser.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
V1 = require './parser_versions/v1'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class RecipeBookParser
|
||||
|
||||
constructor: ->
|
||||
@_parsers =
|
||||
'1': new V1
|
||||
|
||||
parse: (data)->
|
||||
if not data? then throw new Error 'recipe book data is missing'
|
||||
if not data.version? then throw new Error 'version is required'
|
||||
|
||||
parser = @_parsers["#{data.version}"]
|
||||
if not parser?
|
||||
throw new Error "cannot parse version #{data.version} recipe books"
|
||||
|
||||
return parser.parse data
|
||||
@@ -0,0 +1,54 @@
|
||||
###
|
||||
# Crafting Guide - recipe_catalog.coffee
|
||||
#
|
||||
# Copyright (c) 2014 by Redwood Labs
|
||||
# All rights reserved.
|
||||
###
|
||||
|
||||
BaseModel = require './base_model'
|
||||
{Event} = require '../constants'
|
||||
RecipeBookParser = require './recipe_book_parser'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class RecipeCatalog extends BaseModel
|
||||
|
||||
constructor: (attributes={}, options={})->
|
||||
attributes.books ?= []
|
||||
super attributes, options
|
||||
|
||||
@_parser = new RecipeBookParser
|
||||
|
||||
# Public Methods ###############################################################################
|
||||
|
||||
loadBook: (url)->
|
||||
@trigger Event.book.load.started, this, url
|
||||
$.ajax
|
||||
url: url
|
||||
dataType: 'json'
|
||||
success: (data, status, xhr)=> @onBookLoaded(data, status, xhr)
|
||||
error: (xhr, status, error)=> @onBookLoadFailed(error, status, xhr)
|
||||
|
||||
# Event Methods ################################################################################
|
||||
|
||||
onBookLoaded: (data, status, xhr)->
|
||||
try
|
||||
@books.push @_parser.parse data
|
||||
_(@books).sortBy 'name'
|
||||
|
||||
logger.info "loaded recipe book: #{book}"
|
||||
@trigger Event.book.load.succeeded, this, book
|
||||
@trigger Event.book.load.finished, this
|
||||
catch e
|
||||
@onBookLoadFailed error, status, xhr
|
||||
|
||||
|
||||
onBookLoadFailed: (error, status, xhr)->
|
||||
logger.error "failed to load recipe book: #{error}"
|
||||
@trigger Event.book.load.failed, this, error.message
|
||||
@trigger Event.book.load.finished, this
|
||||
|
||||
# Object Overrides #############################################################################
|
||||
|
||||
toString: ->
|
||||
return "RecipeCatalog (#{@cid}) {books:#{@books.length} items}"
|
||||
Reference in New Issue
Block a user