Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions app/actors/PLMActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import akka.actor._
import play.api.libs.json._
import play.api.mvc.RequestHeader
import json._
import json.world._
import models.PLM
import models.User
import log.PLMLogger
Expand All @@ -26,6 +27,21 @@ import play.api.Logger
import java.util.UUID
import models.daos.UserDAOMongoImpl

import java.util.HashMap
import java.nio.file.Files
import java.nio.file.FileSystems
import java.nio.file.FileVisitResult
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes
import java.io.File
import java.io.BufferedWriter
import java.io.BufferedReader
import java.io.FileWriter
import java.io.FileReader
import java.io.IOException

object PLMActor {
def props(actorUUID: String, gitID: String, newUser: Boolean, preferredLang: Option[Lang], lastProgLang: Option[String])(out: ActorRef) = Props(new PLMActor(actorUUID, gitID, newUser, preferredLang, lastProgLang, out))
def propsWithUser(actorUUID: String, user: User)(out: ActorRef) = Props(new PLMActor(actorUUID, user, out))
Expand Down Expand Up @@ -102,6 +118,145 @@ class PLMActor(actorUUID: String, gitID: String, newUser: Boolean, preferredLang
case _ =>
Logger.debug("getExercise: non-correct JSON")
}
case "filterMission" =>
var optMissionText: Option[String] = (msg \ "args" \ "missionText").asOpt[String]
var optAll: Option[Boolean] = (msg \ "args" \ "all").asOpt[Boolean]
var optLangs: Option[Array[String]] = (msg \ "args" \ "languages").asOpt[Array[String]]

(optMissionText.getOrElse(None), optAll.getOrElse(None), optLangs.getOrElse(None)) match {
case (missionText: String, all: Boolean, langs: Array[String]) => {
if(all) {
sendMessage("missionFiltered", Json.obj("filteredMission" -> plm.filterMission(missionText, true, false, null)))
}
else {
sendMessage("missionFiltered", Json.obj("filteredMission" -> plm.filterMission(missionText, false, true, langs)))
}
}
case (_, _, _) => Logger.debug("filterMission: non-correct JSON")
}
case "editorRunSolution" =>
var optLessonID: Option[String] = (msg \ "args" \ "lessonID").asOpt[String]
var optExerciseID: Option[String] = (msg \ "args" \ "exerciseID").asOpt[String]
var optCode: Option[String] = (msg \ "args" \ "code").asOpt[String]
var buggleWorld = GridWorldToJson.JsonToBuggleWorld(plm.game, (msg \ "args" \ "world"))

(optLessonID.getOrElse(None), optExerciseID.getOrElse(None), optCode.getOrElse(None)) match {
case (lessonID:String, exerciseID: String, code: String) =>
plm.currentExercise.setupWorlds(Array(buggleWorld))
var executionSpy: ExecutionSpy = new ExecutionSpy(this, "operations")
var lect: Lecture = plm.game.getCurrentLesson.getCurrentExercise
var exo: Exercise = lect.asInstanceOf[Exercise]
plm.addExecutionSpy(exo, executionSpy, Exercise.WorldKind.CURRENT)
plm.runExercise(lessonID, exerciseID, code)
case (_, _, _) =>
Logger.debug("editorRunSolution: non-correct JSON")
}

case "editorSaveExercise" =>
var optName: Option[String] = (msg \ "args" \ "name").asOpt[String]
var optMission: Option[String] = (msg \ "args" \ "mission").asOpt[String]
var optWorlds: Option[Array[JsObject]] = (msg \ "args" \ "worlds").asOpt[Array[JsObject]]

(optName.getOrElse(None), optMission.getOrElse(None), optWorlds.getOrElse(None)) match {
case (name: String, mission: String, jsWorlds: Array[JsObject]) => {

var worlds: Array[BuggleWorld] = new Array[BuggleWorld](0)
for(jsWorld <- jsWorlds) {
worlds = GridWorldToJson.JsonToBuggleWorld(plm.game, jsWorld) +: worlds
}

/*
Delete old exercise files
*/
class DeleteFiles extends SimpleFileVisitor[Path] {

override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = {
Files.delete(file);
return FileVisitResult.CONTINUE;
}

override def postVisitDirectory(dir: Path, e: IOException): FileVisitResult = {
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
else {
throw e;
}
}
}

var exercisePath = Paths.get("./editor/exercises", name)

if(Files.exists(exercisePath)) {
Files.walkFileTree(exercisePath, new DeleteFiles())
}

Files.createDirectory(exercisePath)

/*
Try writing exercise
*/
try {
var buffer: BufferedWriter = null

/* Writing main class... */
var bufferRead: BufferedReader = new BufferedReader(new FileReader("./editor/classTemplate.java"));
var newLine: String = null
var mainClassContent: String = ""
do {
newLine = bufferRead.readLine()
mainClassContent = mainClassContent + newLine + "\n"
} while(newLine != null)
mainClassContent = mainClassContent.replace("$className", name)
var loadWorldsContent: String = ""
for(world <- worlds) {
loadWorldsContent = loadWorldsContent + "BuggleWorld.newFromFile(\"" + world.getName + "\")," + "\n"
}
mainClassContent = mainClassContent.replace("$loadWorlds", loadWorldsContent)
buffer = new BufferedWriter(new FileWriter("./editor/exercises/" + name + "/" + name + ".java"))
buffer.write(mainClassContent)
buffer.close
bufferRead.close

/* Writing worlds... */
for(world <- worlds) {
buffer = new BufferedWriter(new FileWriter("./editor/exercises/" + name + "/"
+ world.getName + ".map"))
world.writeToFile(buffer)
buffer.close
}

/* Writing missions... */
buffer = new BufferedWriter(new FileWriter("./editor/exercises/" + name + "/" + name + ".html"))
buffer.write(mission)
buffer.close

/* Writing solutions... */
var progLangs = plm._currentExercise.getProgLanguages.toArray(Array[ProgrammingLanguage]())

for(pl <- progLangs) {
var className = name.capitalize + "Entity"
var replace = new HashMap[String, String]()

replace.put("class Editor", "class " + className)

buffer = new BufferedWriter(new FileWriter("./editor/exercises/" + name + "/"
+ className + "." + pl.getExt));
buffer.write(plm.getCompilableContent(replace, pl));
buffer.close
}

}
catch {
case e: IOException =>
Logger.debug("Error while writing world file")
}
}
case (_) =>
Logger.debug("editorSaveExercise: non-correct JSON")
}

case "getExercise" =>
var optLessonID: Option[String] = (msg \ "args" \ "lessonID").asOpt[String]
var optExerciseID: Option[String] = (msg \ "args" \ "exerciseID").asOpt[String]
Expand All @@ -121,6 +276,34 @@ class PLMActor(actorUUID: String, gitID: String, newUser: Boolean, preferredLang
"exercise" -> LectureToJson.lectureWrites(lecture, plm.programmingLanguage, plm.getStudentCode, plm.getInitialWorlds, plm.getSelectedWorldID)
))
}
case "getExerciseToEdit" =>
var optLessonID: Option[String] = (msg \ "args" \ "lessonID").asOpt[String]
var optExerciseID: Option[String] = (msg \ "args" \ "exerciseID").asOpt[String]
var lecture: Lecture = null;
var executionSpy: ExecutionSpy = new ExecutionSpy(this, "operations")
var demoExecutionSpy: ExecutionSpy = new ExecutionSpy(this, "demoOperations")
(optLessonID.getOrElse(None), optExerciseID.getOrElse(None)) match {
case (lessonID:String, exerciseID: String) =>
lecture = plm.switchExercise(lessonID, exerciseID, executionSpy, demoExecutionSpy)
case (lessonID:String, _) =>
lecture = plm.switchLesson(lessonID, executionSpy, demoExecutionSpy)
case (_, _) =>
Logger.debug("getExerciseToEdit: non-correct JSON")
}
if(lecture != null) {
var progLangs = lecture.asInstanceOf[Exercise].getProgLanguages.toArray(Array[ProgrammingLanguage]())
var solutionCodes: Array[(String,String)] = new Array[(String,String)](progLangs.length)
var i = 0
for(progLang <- progLangs) {
solutionCodes(i) = (progLang.getLang, plm.getSolutionCode(progLang))
i = i + 1
}

sendMessage("exerciseToEdit", Json.obj(
"exercise" -> LectureToJson.lectureWritesForEditor(lecture, plm.programmingLanguage, plm.getStudentCode, plm.getInitialWorlds, plm.getSelectedWorldID, solutionCodes)
))
}

case "runExercise" =>
var optLessonID: Option[String] = (msg \ "args" \ "lessonID").asOpt[String]
var optExerciseID: Option[String] = (msg \ "args" \ "exerciseID").asOpt[String]
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/Application.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ object Application extends Controller {
def exercise(lessonID: String, exerciseID: String) = Action { implicit request =>
Ok(views.html.index("Accueil"))
}

def editor = Action { implicit request =>
Ok(views.html.index("Accueil"))
}

def editorLoadLesson(lessonID: String) = Action { implicit request =>
Ok(views.html.index("Accueil"))
}

def editorLoadExercise(lessonID: String, exerciseID: String) = Action { implicit request =>
Ok(views.html.index("Accueil"))
}

def specRunner() = Action { implicit request =>
Ok(views.html.specRunner())
Expand Down
20 changes: 20 additions & 0 deletions app/json/LectureToJson.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ object LectureToJson {

return json
}

def lectureWritesForEditor (lecture: Lecture, progLang: ProgrammingLanguage, code: String,
initialWorlds: Array[World], selectedWorldID: String,
solutionCodes: Array[(String,String)]): JsValue = {

var jsonSolutions = Json.obj()
for(solution <- solutionCodes) {
jsonSolutions = jsonSolutions.as[JsObject] ++ Json.obj(
solution._1.toLowerCase -> solution._2
)
}

var json = lectureWrites(lecture, progLang, code, initialWorlds, selectedWorldID)
json = json.as[JsObject] ++ Json.obj(
"missionHTML" -> lecture.getRawMission(),
"solutionCodes" -> jsonSolutions
)

return json
}

def instructionsWrite(lecture: Lecture, progLang: ProgrammingLanguage, initialWorlds: Array[World]): JsValue = {
return Json.obj(
Expand Down
43 changes: 43 additions & 0 deletions app/json/entity/AbstractBuggleToJson.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package json.entity

import java.awt.Color

import play.api.libs.json._
import plm.universe.bugglequest.AbstractBuggle
import plm.universe.bugglequest.SimpleBuggle
import plm.universe.bugglequest.BuggleWorld
import plm.universe.Direction
import play.api.libs.json.Json.toJsFieldJsValueWrapper

object AbstractBuggleToJson {
Expand All @@ -15,4 +20,42 @@ object AbstractBuggleToJson {
"carryBaggle" -> abstractBuggle.isCarryingBaggle()
)
}

def JsonSimpleBugglesWrite(buggleWorld: BuggleWorld, jsSimpleBuggles: JsObject): Array[SimpleBuggle] = {
var bugglesID = jsSimpleBuggles.keys
var newBuggles: Array[SimpleBuggle] = new Array[SimpleBuggle](bugglesID.size)
var i = 0;
for(buggleID <- bugglesID) {
var optBuggle: Option[JsObject] = (jsSimpleBuggles \ buggleID).asOpt[JsObject]
optBuggle.getOrElse(None) match {
case buggle: JsObject =>
newBuggles(i) = JsonSimpleBuggleWrite(buggleWorld, buggleID, buggle)
i += 1
}
}
return newBuggles
}

def JsonSimpleBuggleWrite(buggleWorld: BuggleWorld, name: String, jsSimpleBuggle: JsObject): SimpleBuggle = {
var optX: Option[Int] = (jsSimpleBuggle \ "x").asOpt[Int]
var optY: Option[Int] = (jsSimpleBuggle \ "y").asOpt[Int]
var optColor: Option[Array[Int]] = (jsSimpleBuggle \ "color").asOpt[Array[Int]]
var optDirection: Option[Int] = (jsSimpleBuggle \ "direction").asOpt[Int]
var optcarryBaggle: Option[Boolean] = (jsSimpleBuggle \ "carryBaggle").asOpt[Boolean]

(optX.getOrElse(None), optY.getOrElse(None), optColor.getOrElse(None),
optDirection.getOrElse(None), optcarryBaggle.getOrElse(None)) match {
case (x: Int, y: Int, color: Array[Int], directionNb: Int, carryBaggle: Boolean) => {
var direction = directionNb match {
case Direction.NORTH_VALUE => Direction.NORTH
case Direction.EAST_VALUE => Direction.EAST
case Direction.WEST_VALUE => Direction.WEST
case Direction.SOUTH_VALUE => Direction.SOUTH
}
return new SimpleBuggle(buggleWorld, name, x, y, direction,
new Color(color(0), color(1), color(2), color(3)),
new Color(42, 42, 42, 255))
}
}
}
}
Loading