Skip to content

Commit

Permalink
Merge pull request #332 from unepwcmc/gdoc-indicator-working
Browse files Browse the repository at this point in the history
GDoc Importer actually works (with command and update)
  • Loading branch information
adammulligan committed May 7, 2014
2 parents 43431b6 + 753bdab commit f550281
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 180 deletions.
116 changes: 90 additions & 26 deletions server/lib/gdoc_indicator_importer.coffee
Original file line number Diff line number Diff line change
@@ -1,45 +1,109 @@
Promise = require 'bluebird'
Indicator = require('../models/indicator').model
_ = require 'underscore'

GDocWrapper = require('./gdoc_wrapper')
Indicator = require('../models/indicator').model
Theme = require('../models/theme').model

DEFAULT_INDICATOR_DEFINITION =
"period": "yearly",
"xAxis": "year",
"yAxis": "value",
"geometryField": "geometry",
"fields": [
{
"source": {
"name": "periodStart",
"type": "integer"
},
"name": "year",
"type": "integer"
}, {
"source": {
"name": "value",
"type": "text"
},
"name": "value",
"type": "integer"
}, {
"source": {
"name": "text",
"type": "text"
},
"name": "text",
"type": "text"
}
]

mergeAttributesWithDefaults = (attributes) ->
attributes.indicatorDefinition = _.extend(
DEFAULT_INDICATOR_DEFINITION, attributes.indicatorDefinition
)
return attributes

extractRangesFromWorksheet = (worksheet) ->
index = 2

ranges = []
while (range = worksheet[index.toString()])?
ranges.push(
threshold: range['1'].value
text: range['2'].value
minValue: parseFloat(range['1'].value, 10)
message: range['2'].value
)
index = index + 1

return ranges

module.exports =
import: (key) ->

spreadsheet = null
definition = {}

GDocWrapper.importByKey(key).then((spr)->
spreadsheet = spr

spreadsheet.getWorksheetData('Definition')
).then((worksheet) ->

definition.name = worksheet['2']['1'].value
definition.theme = worksheet['2']['2'].value
definition.unit = worksheet['2']['3'].value

spreadsheet.getWorksheetData('Ranges')
).then((worksheet) ->

definition.indicatorationConfig =
module.exports = class GDocIndicatorImporter
constructor: (key) ->
@indicatorProperties = {
indicatorationConfig:
source: 'gdoc'
spreadsheet_key: key
range: extractRangesFromWorksheet(worksheet)
}

@import: (key) ->
GDocWrapper.importByKey(key).then((spreadsheet) ->
Promise.all([
spreadsheet.getWorksheetData('Definition'),
spreadsheet.getWorksheetData('Ranges')
])
).spread((definitionWorksheet, rangesWorksheet) ->
indicatorImporter = new GDocIndicatorImporter(key)
indicatorImporter.setDefinitionFromWorksheet(
definitionWorksheet
).then( ->
indicatorImporter.setRangesFromWorksheet(rangesWorksheet)
indicatorImporter.createOrUpdateIndicator()
)
)

setDefinitionFromWorksheet: (worksheet) ->
themeTitle = worksheet['2']['2'].value

indicator = Indicator.buildWithDefaults(definition)
return Theme.findOrCreateByTitle(themeTitle).then((theme) =>
_.extend(@indicatorProperties, {
short_name: worksheet['2']['1'].value
title: worksheet['2']['1'].value
theme: theme._id
indicatorDefinition:
unit: worksheet['2']['3'].value
short_unit: worksheet['2']['3'].value
})
)

Promise.promisify(indicator.save, indicator)()
setRangesFromWorksheet: (worksheet) ->
@indicatorProperties.indicatorationConfig.range = extractRangesFromWorksheet(
worksheet
)

createOrUpdateIndicator: ->
existingIndicator = Promise.promisify(Indicator.findOne, Indicator)(
'indicatorationConfig.spreadsheet_key': @indicatorProperties.indicatorationConfig.spreadsheet_key
).then( (indicator) =>
@indicatorProperties = mergeAttributesWithDefaults(@indicatorProperties)
if indicator?
Promise.promisify(indicator.update, indicator)(@indicatorProperties)
else
Promise.promisify(Indicator.create, Indicator)(@indicatorProperties)
)
54 changes: 3 additions & 51 deletions server/models/indicator.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,10 @@ replaceThemeNameWithId = (indicators) ->
deferred = Q.defer()

getThemeFromTitle = (indicator, callback) ->
Theme.findOne(title: indicator.theme, (err, theme) ->
if err? or !theme?
return callback(err)

Theme.findOrCreateByTitle(indicator.theme).then((theme) ->
indicator.theme = theme._id
callback(null, indicator)
)
callback(null, theme)
).catch(callback)

async.map(indicators, getThemeFromTitle, (err, indicatorsWithThemes) ->
if err?
Expand Down Expand Up @@ -287,7 +284,6 @@ indicatorSchema.methods.generateMetadataCSV = ->

return deferred.promise


# Add currentYValue to a collection of indicators
indicatorSchema.statics.calculateCurrentValues = (indicators, callback) ->
currentValueGatherers = []
Expand Down Expand Up @@ -384,50 +380,6 @@ indicatorSchema.statics.convertNestedParametersToAssociationIds = (attributes) -

return attributes

DEFAULT_INDICATOR_DEFINITION =
"unit": "landings",
"short_unit": "landings",
"period": "yearly",
"xAxis": "year",
"yAxis": "value",
"geometryField": "geometry",
"fields": [
{
"source": {
"name": "periodStart",
"type": "epoch"
},
"name": "year",
"type": "integer"
}, {
"source": {
"name": "value",
"type": "integer"
},
"name": "value",
"type": "integer"
}, {
"source": {
"name": "text",
"type": "text"
},
"name": "text",
"type": "text"
}
]

indicatorSchema.statics.buildWithDefaults = (attributes) ->
definition =
unit: attributes.unit
short_unit: attributes.unit

definition = _.extend(DEFAULT_INDICATOR_DEFINITION, definition)
new Indicator(
title: attributes.name
short_name: attributes.name
indicatorDefinition: definition
)

Indicator = mongoose.model('Indicator', indicatorSchema)

module.exports = {
Expand Down
19 changes: 17 additions & 2 deletions server/models/theme.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ mongoose = require('mongoose')
fs = require('fs')
_ = require('underscore')
async = require('async')
Indicator = require('./indicator').model
HeadlineService = require('../lib/services/headline')
Q = require('q')
Promise = require('bluebird')

Indicator = require('./indicator').model
HeadlineService = require('../lib/services/headline')
pageModelMixin = require('../mixins/page_model.coffee')

themeSchema = mongoose.Schema(
Expand Down Expand Up @@ -140,6 +141,20 @@ themeSchema.methods.populateIndicators = ->
Q.fcall(=> @)
)

themeSchema.statics.findOrCreateByTitle = (title) ->
new Promise((resolve, reject) =>
@findOne({title: title}, (err, theme) ->
return reject(err) if err?
if theme?
resolve(theme)
else
Promise.promisify(Theme.create, Theme)(title: title).then(
resolve, reject
)

)
)

Theme = mongoose.model('Theme', themeSchema)

module.exports = {
Expand Down
Loading

0 comments on commit f550281

Please sign in to comment.