Skip to content

Commit

Permalink
Merge pull request #107 from uts-cic/develop
Browse files Browse the repository at this point in the history
tap-106 Issue with Athanor queries
  • Loading branch information
andrewresearch authored Nov 6, 2017
2 parents 5190c2c + e728bf8 commit 28616ff
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 154 deletions.
6 changes: 3 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

name := "tap"

version := "3.0.8"
version := "3.0.9"

scalaVersion := "2.12.3"

Expand Down Expand Up @@ -105,8 +105,8 @@ dockerExposedPorts := Seq(9000) // sbt docker:publishLocal

javaOptions in Universal ++= Seq(
// -J params will be added as jvm parameters
"-J-Xmx6g",
"-J-Xms3g"
"-J-Xmx4g",
"-J-Xms2g"

// others will be added as app parameters
// "-Dproperty=true",
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/controllers/GraphQlController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class GraphQlController @Inject() (assets: AssetsFinder, gqlSchema: GraphqlSchem
def process(query:String,name:Option[String],variables:JsObject):Future[Result] = QueryParser.parse(query) match {
case Success(queryAst) => executeGraphQLQuery(queryAst, name, variables)
case Failure(error: SyntaxError) => Future.successful(BadRequest(error.getMessage))
case _ => Future.successful(BadRequest("There was a problem with the request to TAP graphql."))
}

def executeGraphQLQuery(query: Document, name: Option[String], vars: JsObject):Future[Result] = {
Expand Down
49 changes: 4 additions & 45 deletions src/main/scala/handlers/ExternalAnalysisHandler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,62 +20,21 @@ import javax.inject.Inject

import models.Results.StringListResult
import play.api.Logger
import play.api.libs.ws.{WSClient, WSRequest, WSResponse}
import tap.pipelines.materialize.PipelineContext.executor

import tap.analysis.athanor.AthanorClient

import scala.concurrent.Future
import scala.concurrent.duration.DurationInt
/**
* Created by andrew@andrewresearch.net on 19/9/17.
*/
class ExternalAnalysisHandler @Inject() (wsClient: WSClient) {
class ExternalAnalysisHandler @Inject() (athanorClient: AthanorClient) {

val logger: Logger = Logger(this.getClass)

def analyseWithAthanor(text:String,grammar:Option[String]):Future[StringListResult] = {
//logger.info(s"Analysing with athanor: $text")
val parameter = "?grammar=" + grammar.getOrElse("analytic")
val url = "http://athanor.utscic.edu.au/v2/analyse/text/rhetorical" + parameter
logger.info(s"Creating request to: $url")
val request: WSRequest = wsClient.url(url)

val athanorRequest: WSRequest = request
.withHttpHeaders("Accept" -> "application/json")
.withRequestTimeout(30000.millis)

val futureResponse: Future[WSResponse] = athanorRequest.post(text)
//try {
case class AthanorMsg(message: String, results: Vector[Vector[String]])

import play.api.libs.functional.syntax._
import play.api.libs.json._ //scalastyle:ignore

implicit val AMWrites: Writes[AthanorMsg] = (
(JsPath \ "message").write[String] and
(JsPath \ "results").write[Vector[Vector[String]]]
) (unlift(AthanorMsg.unapply))

implicit val AMReads: Reads[AthanorMsg] = (
(JsPath \ "message").read[String] and
(JsPath \ "results").read[Vector[Vector[String]]]
) (AthanorMsg.apply _)
logger.warn("About to try and get result...")
val result: Future[StringListResult] = {
futureResponse.map { response =>
val res = response.json.as[AthanorMsg].results
StringListResult(res,"ok")
}
val errMsg = "There was a problem connecting to the Athanor server."
futureResponse.recover {
case e: Any => {
val msg = s"$errMsg: $e"
logger.error(msg)
StringListResult(Vector(),msg)
}
}.asInstanceOf[Future[StringListResult]]
}
result
athanorClient.process(text,url)
}

}
}
98 changes: 98 additions & 0 deletions src/main/scala/tap/analysis/athanor/AthanorClient.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright 2016-2017 original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package tap.analysis.athanor

import javax.inject.Inject

import models.Results.StringListResult
import play.api.Logger
import play.api.libs.ws.{WSClient, WSRequest, WSResponse}

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.duration._ // scalastyle:ignore


/**
* Created by andrew@andrewresearch.net on 6/11/17.
*/

class AthanorClient @Inject() (wsClient: WSClient)(implicit ec: ExecutionContext) {

val logger: Logger = Logger(this.getClass)


def process(text:String,url:String):Future[StringListResult] = {
//logger.info(s"Analysing with athanor: $text")

val request: WSRequest = wsClient.url(url)

val athanorRequest: WSRequest = request
.withHttpHeaders("Accept" -> "application/json")
.withRequestTimeout(30000.millis)

val futureResponse: Future[WSResponse] = athanorRequest.post(text)


val result: Future[StringListResult] = {
val decoded = futureResponse.map { response =>
val res = decodeRepsonse(response)
StringListResult(res,"ok")
}
val errMsg = "There was a problem connecting to the Athanor server."
futureResponse.recover {
case e: Any => {
val msg = s"$errMsg: $e"
logger.error(msg)
StringListResult(Vector(),msg)
}
//case _ => logger.error(errMsg)
}
decoded
}
result
}

case class AthanorMsg(message: String, results: Vector[Vector[String]])

def decodeRepsonse(response:WSResponse): Vector[Vector[String]] = {
val resBody = response.body
if(resBody.nonEmpty && resBody.contains(":[[")) {
logger.debug("Decoding response: "+ resBody)

import play.api.libs.functional.syntax._ //scalastyle:ignore
import play.api.libs.json._ //scalastyle:ignore

implicit val AMWrites: Writes[AthanorMsg] = (
(JsPath \ "message").write[String] and
(JsPath \ "results").write[Vector[Vector[String]]]
) (unlift(AthanorMsg.unapply))

implicit val AMReads: Reads[AthanorMsg] = (
(JsPath \ "message").read[String] and
(JsPath \ "results").read[Vector[Vector[String]]]
) (AthanorMsg.apply _)

val athanorMsg:AthanorMsg = response.json.as[AthanorMsg]
logger.debug("Athanor message: " + athanorMsg.message)
logger.debug("Athanor results: " + athanorMsg.results)
athanorMsg.results
} else {
logger.error("There was a problem: " + resBody) //TODO If we get to here, we need to return the message to the client!!
Vector()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package tap.services.analytics.aggregators
//package tap.services.analytics.aggregators

/*
def aggregate(text:String):Future[AllComplexity] = aggregate(InputData("","",text.split("\n").toList))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package tap.services.feedback
//package tap.services.feedback

/**
* Created by andrew@andrewresearch.net on 15/07/2016.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package tap.services.feedback
//package tap.services.feedback

/**
* Created by andrew@andrewresearch.net on 15/07/2016.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
package tap.services.feedback

/**
* Created by andrew@andrewresearch.net on 20/07/2016.
*/
object SpellText {
val showCounts = false
def docVeryFewErrors="Your document appears to have very few words that AWA has not recognised which normally means that your spelling is good. However, you should always proofread your writing before submitting for assessment."
def docSomeErrors(spellCount:Int) = "Your document appears to have a number of words that AWA does not recognise. Try using word processing software to locate the specific mistakes, correct your document, and try submitting it again to AWA."
def docQuiteAlotErrors(spellCount:Int) = "Your document has quite a lot of words that AWA does not recognise. With this many errors, AWA may not accurately detect other features in your writing. Try using word processing software to find the specific errors, correct them, and resubmit your document."
def docTooManyErrors(spellCount:Int) = "Your document appears to have quite a lot of spelling errors which will prevent AWA from analysing it properly it properly. Try using word processing software to find the specific errors, correct them, and resubmit your document."
def paraNoErrors = "There doesn't appear to be any spelling errors in this paragraph - Well done."
def paraSomeErrors = "There are words in this paragraph that AWA does not recognise. Please check your spelling and grammar."
}

object RhetoricalMovesText {
def docMissingMoves = "Your document appears to be lacking one or more of the key sentence level features that AWA expects to find in reflective writing. These are represented as coloured icons located at the beginning of sentences. If you need to check what each icon represents, click on the guidance button on the left."
def docFewMoves = "In reflective writing, AWA expects to find more sentence level features than what has been identified in your document. These are represented as coloured icons located at the beginning of sentences. This may be intentional on your part, and it does not necessarily mean that your writing is not good, but you should check this with your assessment rubric or one of your subject tutors as your writing may not be as reflective as it should be."
def docImbalance = "Your document does not appear to have a good balance of the key sentence level features that AWA expects to find in reflective writing. These are represented as coloured icons located at the beginning of sentences. In reflective writing, AWA does not expect to have very few of one type of sentence feature together with a large quantity of another. Check this against your assessment rubric or with one of your subject tutors as you may be missing a key element of good reflective writing."
def docTooMany = "AWA does not expect to find this many sentence level features in your writing. These are represented as coloured icons located at the beginning of sentences. Ensure that your writing is of an appropriate style for your subject. AWA does not check style so you may need to refer to your assessment rubric or check with a subject tutor."
def default = "AWA has identified some sentence level features in your writing. These are represented as coloured icons located at the beginning of sentences. Check your assessment rubric to ensure that your document is structured according to the subject requirements."

}

object ExpressionText {
def noExpressions = "In this paragraph, AWA was unable to identify expressions of self-critique, expressions of knowledge/learning, or words that evoke strong feelings."
def onlyEmotion = "In this paragraph, AWA was unable to identify expressions of self-critique or knowledge/learning."
def default = ""

def strongAffect = "You appear to have used quite a number of words that evoke strong feelings. An important aspect of reflective writing is stating how you feel about the key challenge/s that you are reflecting upon."
def moderateAffect = "This paragraph includes the use of some words that evoke strong feelings (dashed underline). Reflective writing uses this kind of language to express how you feel about a problem or challenge. Have you done this in this paragraph?"
def weakAffect = "Good reflective writing requires more than just description. Are you expressing how you feel about the key challenge/s that you are reflecting on? Check your assignment requirements to see if this is something that should be included at this point in your writing."
}

object DummyText {

/*
private def dummyParagraphFeedback(quantity:Int) = (1 to quantity).map( parNum => AwaOutputData("text","Dummy Paragraph Feedback",List("This is placeholder feedbackQuery for paragraph "+parNum,"It is intended for testing purposes, and to assist with UI development. Actual feedbackQuery may be shorter or longer than this."),parNum,parNum,0,0)).toList
private def dummyDocumentFeedback = AwaOutputData("text","Dummy Document Feedback",List("This is placeholder feedbackQuery for the document","It is intended for testing and UI development. This type of feedbackQuery will contain comments that apply to the document as a whole."),0,0,0,0)
*/

}
//package tap.services.feedback
//
///**
// * Created by andrew@andrewresearch.net on 20/07/2016.
// */
//object SpellText {
// val showCounts = false
// def docVeryFewErrors="Your document appears to have very few words that AWA has not recognised which normally means that your spelling is good. However, you should always proofread your writing before submitting for assessment."
// def docSomeErrors(spellCount:Int) = "Your document appears to have a number of words that AWA does not recognise. Try using word processing software to locate the specific mistakes, correct your document, and try submitting it again to AWA."
// def docQuiteAlotErrors(spellCount:Int) = "Your document has quite a lot of words that AWA does not recognise. With this many errors, AWA may not accurately detect other features in your writing. Try using word processing software to find the specific errors, correct them, and resubmit your document."
// def docTooManyErrors(spellCount:Int) = "Your document appears to have quite a lot of spelling errors which will prevent AWA from analysing it properly it properly. Try using word processing software to find the specific errors, correct them, and resubmit your document."
// def paraNoErrors = "There doesn't appear to be any spelling errors in this paragraph - Well done."
// def paraSomeErrors = "There are words in this paragraph that AWA does not recognise. Please check your spelling and grammar."
//}
//
//object RhetoricalMovesText {
// def docMissingMoves = "Your document appears to be lacking one or more of the key sentence level features that AWA expects to find in reflective writing. These are represented as coloured icons located at the beginning of sentences. If you need to check what each icon represents, click on the guidance button on the left."
// def docFewMoves = "In reflective writing, AWA expects to find more sentence level features than what has been identified in your document. These are represented as coloured icons located at the beginning of sentences. This may be intentional on your part, and it does not necessarily mean that your writing is not good, but you should check this with your assessment rubric or one of your subject tutors as your writing may not be as reflective as it should be."
// def docImbalance = "Your document does not appear to have a good balance of the key sentence level features that AWA expects to find in reflective writing. These are represented as coloured icons located at the beginning of sentences. In reflective writing, AWA does not expect to have very few of one type of sentence feature together with a large quantity of another. Check this against your assessment rubric or with one of your subject tutors as you may be missing a key element of good reflective writing."
// def docTooMany = "AWA does not expect to find this many sentence level features in your writing. These are represented as coloured icons located at the beginning of sentences. Ensure that your writing is of an appropriate style for your subject. AWA does not check style so you may need to refer to your assessment rubric or check with a subject tutor."
// def default = "AWA has identified some sentence level features in your writing. These are represented as coloured icons located at the beginning of sentences. Check your assessment rubric to ensure that your document is structured according to the subject requirements."
//
//}
//
//object ExpressionText {
// def noExpressions = "In this paragraph, AWA was unable to identify expressions of self-critique, expressions of knowledge/learning, or words that evoke strong feelings."
// def onlyEmotion = "In this paragraph, AWA was unable to identify expressions of self-critique or knowledge/learning."
// def default = ""
//
// def strongAffect = "You appear to have used quite a number of words that evoke strong feelings. An important aspect of reflective writing is stating how you feel about the key challenge/s that you are reflecting upon."
// def moderateAffect = "This paragraph includes the use of some words that evoke strong feelings (dashed underline). Reflective writing uses this kind of language to express how you feel about a problem or challenge. Have you done this in this paragraph?"
// def weakAffect = "Good reflective writing requires more than just description. Are you expressing how you feel about the key challenge/s that you are reflecting on? Check your assignment requirements to see if this is something that should be included at this point in your writing."
//}
//
//object DummyText {
//
// /*
// private def dummyParagraphFeedback(quantity:Int) = (1 to quantity).map( parNum => AwaOutputData("text","Dummy Paragraph Feedback",List("This is placeholder feedbackQuery for paragraph "+parNum,"It is intended for testing purposes, and to assist with UI development. Actual feedbackQuery may be shorter or longer than this."),parNum,parNum,0,0)).toList
//
// private def dummyDocumentFeedback = AwaOutputData("text","Dummy Document Feedback",List("This is placeholder feedbackQuery for the document","It is intended for testing and UI development. This type of feedbackQuery will contain comments that apply to the document as a whole."),0,0,0,0)
// */
//
//}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package tap.services.feedback
//package tap.services.feedback

/**
* Created by andrew@andrewresearch.net on 15/07/2016.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package tap.services.feedback
//package tap.services.feedback

/**
* Created by andrew@andrewresearch.net on 15/07/2016.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tap.services.analytics.analysers
//package tap.services.analytics.analysers

/**
* Created by andrew@andrewresearch.net on 9/1/17.
Expand Down
Loading

0 comments on commit 28616ff

Please sign in to comment.