Files
website/src/coffee/models/editable_file.coffee
T

132 lines
4.2 KiB
CoffeeScript

###
Crafting Guide - editable_file.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
BaseModel = require './base_model'
{Event} = require '../constants'
w = require 'when'
########################################################################################################################
module.exports = class EditableFile extends BaseModel
@MimeTypes = MimeTypes = [
{ pattern:/\.cg$/i, text:'text/plain' }
{ pattern:/\.png$/i, text:'image/png' }
{ pattern:/\.gif$/i, text:'image/gif' }
{ pattern:/\.jpg$/i, text:'image/jpeg' }
{ pattern:/\.jpeg$/i, text:'image/jpeg' }
]
@Status = Status = {
'unknown': 'unknown'
'checking': 'checking'
'empty': 'empty'
'clean': 'clean'
'dirty': 'dirty'
}
constructor: (attributes={}, options={})->
attributes.fileName ?= ''
attributes.path ?= ''
attributes.sha ?= null
attributes.status ?= Status.unknown
super
@client = options.client
@_encodedData = null
@on Event.change + ':fileName', => @_mimeType = null
# Public Methods ###############################################################################
getDecodedData: (targetEncoding='utf8')->
return new Buffer(@encodedData, 'base64').toString(targetEncoding)
setDecodedData: (text, sourceEncoding='utf8')->
@encodedData = new Buffer(text, sourceEncoding).toString('base64')
# Property Methods #############################################################################
getDataAsText: ->
if not @_dataAsText
@_dataAsText = new Buffer(@encodedData, 'base64').toString('utf8')
return @_dataAsText
getEncodedData: ->
return @_encodedData
setEncodedData: (newEncodedData)->
oldEncodedData = @_encodedData
return if newEncodedData is oldEncodedData
@_encodedData = newEncodedData
@_updateStatusForNewData()
@trigger Event.change + ':encodedData', this, oldEncodedData, newEncodedData
@trigger Event.change, this
getFullPath: ->
return "#{@path}/#{@fileName}"
getMimeType: ->
if not @_mimeType?
for mimeType in MimeTypes
if mimeType.pattern.test @fileName
@_mimeType = mimeType.text
break
return @_mimeType
isValid: ->
return @status in [ Status.clean, Status.dirty ]
Object.defineProperties @prototype,
encodedData: { get:@prototype.getEncodedData, set:@prototype.setEncodedData }
fullPath: { get:@prototype.getFullPath }
imageUrl: { get:@prototype.getImageUrl }
mimeType: { get:@prototype.getMimeType }
valid: { get:@prototype.isValid }
# BaseModel Overrides ##########################################################################
fetch: ->
if not @client? then throw new Error 'EditableFile must be given a client to fetch with'
@status = Status.checking
@client.fetchFile path:@fullPath
.then (response)=>
data = response.json.data
if data.sha?
@encodedData = data.content
@sha = data.sha
else
@status = Status.empty
return this
save: (commitMessage)->
return w(true) if @status is Status.clean
return w(true) unless @encodedData?
if not @valid then return w.reject new Error "cannot save with an invalid status: #{@status}"
commitMessage ?= "User-submitted update to #{@fileName} from #{global.hostName}"
@client.updateFile content:@encodedData, message:commitMessage, path:@fullPath, sha:@sha
# Private Methods ##############################################################################
_updateStatusForNewData: ->
switch @status
when Status.unknown
@status = Status.dirty
when Status.checking
@status = Status.clean
when Status.empty
@status = Status.dirty
when Status.clean
@status = Status.dirty