Add concept map view to artisans.

This commit is contained in:
Rob 2016-07-19 17:58:10 -07:00
parent fd17793819
commit 75e3c54d54
4 changed files with 193 additions and 1 deletions

View file

@ -51,6 +51,7 @@ module.exports = class CocoRouter extends Backbone.Router
'artisans/level-tasks': go('artisans/LevelTasksView')
'artisans/solution-problems': go('artisans/SolutionProblemsView')
'artisans/thang-tasks': go('artisans/ThangTasksView')
'artisans/level-concepts': go('artisans/LevelConceptMap')
'beta': go('HomeView')

View file

@ -10,4 +10,7 @@ block content
|Level Tasks
div
a(href="/artisans/solution-problems")
|Solution Problems
|Solution Problems
div
a(href="/artisans/level-concepts")
|Level Concept Map

View file

@ -0,0 +1,20 @@
// DNT
extends /templates/base
block content
#solution-problems-view
div
a(href='/artisans')
span.glyphicon.glyphicon-chevron-left
span Artisans Home
br
table.table.table-striped#level-table
tr
th Level Name
th Concepts Detected
for level in (view.parsedLevels || [])
tr
td(style="width:10%")= level.level.get('name')
td
for tag in (level.tags || [])
span.label.label-primary(style='margin-right: 10px; float: left; line-height: 20px; margin-bottom: 10px')= tag

View file

@ -0,0 +1,168 @@
RootView = require 'views/core/RootView'
template = require 'templates/artisans/concept-map-view'
Level = require 'models/Level'
Campaign = require 'models/Campaign'
CocoCollection = require 'collections/CocoCollection'
Campaigns = require 'collections/Campaigns'
Levels = require 'collections/Levels'
parser = new esper().realm.parser
module.exports = class LevelConceptMap extends RootView
template: template
id: 'solution-problems-view'
excludedCampaigns = [
# Misc. campaigns
'picoctf', 'auditions'
# Campaign-version campaigns
#'dungeon', 'forest', 'desert', 'mountain', 'glacier'
# Test campaigns
'dungeon-branching-test', 'forest-branching-test', 'desert-branching-test'
# Course-version campaigns
#'intro', 'course-2', 'course-3', 'course-4', 'course-5', 'course-6'
]
includedLanguages = [
'javascript'
]
excludedLevelSnippets = [
'treasure', 'brawl', 'siege'
]
unloadedCampaigns: 0
campaignLevels: {}
loadedLevels: {}
parsedLevels: []
problemCount: 0
initialize: ->
@campaigns = new Campaigns([])
@listenTo(@campaigns, 'sync', @onCampaignsLoaded)
@supermodel.trackRequest(@campaigns.fetch(
data:
project:'slug'
))
onCampaignsLoaded: (campCollection) ->
for campaign in campCollection.models
campaignSlug = campaign.get('slug')
continue if campaignSlug in excludedCampaigns
@unloadedCampaigns++
@campaignLevels[campaignSlug] = new Levels()
@listenTo(@campaignLevels[campaignSlug], 'sync', @onLevelsLoaded)
@supermodel.trackRequest(@campaignLevels[campaignSlug].fetchForCampaign(campaignSlug,
data:
project: 'thangs,name,slug,campaign'
))
onLevelsLoaded: (lvlCollection) ->
for level in lvlCollection.models
@loadedLevels[level.get('slug')] = level
if --@unloadedCampaigns is 0
@onAllLevelsLoaded()
onAllLevelsLoaded: ->
for levelSlug, level of @loadedLevels
unless level?
console.error 'Level Slug doesn\'t have associated Level', levelSlug
continue
isBad = false
for word in excludedLevelSnippets
if levelSlug.indexOf(word) isnt -1
isBad = true
continue if isBad
thangs = level.get 'thangs'
component = null
thangs = _.filter(thangs, (elem) ->
return _.findWhere(elem.components, (elem2) ->
if elem2.config?.programmableMethods?
component = elem2
return true
)
)
if thangs.length > 1
console.warn 'Level has more than 1 programmableMethod Thangs', levelSlug
continue
unless component?
console.error 'Level doesn\'t have programmableMethod Thang', levelSlug
continue
plan = component.config.programmableMethods.plan
@parsedLevels.push
level: level
tags: @tagLevel _.find plan.solutions, (s) -> s.language is 'javascript'
@renderSelectors '#level-table'
tagLevel: (src) ->
return [] if not src?.source?
try
ast = parser(src.source)
catch e
return ['parse error: ' + e.message]
tags = {}
process = (n) ->
return unless n?
switch n.type
when "Program", "BlockStatement"
process(n) for n in n.body
when "FunctionDeclaration"
tags['function-def'] = true
if n.params > 0
tags['function-params:' + n.params.length] = true
process(n.body)
when "ExpressionStatement"
process(n.expression)
when "CallExpression"
process(n.callee)
when "MemberExpression"
if n.object?.name is 'hero'
tags["hero." + n.property.name] = true
when "WhileStatement"
if n.test.type is 'Literal' and n.test.value is true
tags['while-true'] = true
else
tags['while'] = true
process(n.test)
process(n.body)
when "ForStatement"
tags['for'] = true
process(n.init)
process(n.test)
process(n.update)
process(n.body)
when "IfStatement"
tags['if'] = true
process(n.test)
process(n.consequent)
process(n.alternate)
when "Literal"
if n.value is true
tags['true'] = true
else
tags['literal:' + typeof n.value] = true
when "BinaryExpression","LogicalExpression"
process(n.left)
process(n.right)
tags[n.operator] = true
when "AssignmentExpression"
tags['assign:' + n.operator] = true
process(n.right)
else
tags[n.type] = true
process ast
Object.keys(tags)