ReportBuilder.scala 3.61 KB
Newer Older
1
2
3
4
5
6
package nl.lumc.sasc.biopet.core.report

import java.io.{ PrintWriter, File }

import nl.lumc.sasc.biopet.core.ToolCommand
import nl.lumc.sasc.biopet.core.summary.Summary
7
import org.fusesource.scalate.{ TemplateSource, TemplateEngine }
8
9
10
11
12
13
14
15

import scala.io.Source

/**
 * Created by pjvan_thof on 3/27/15.
 */
trait ReportBuilder extends ToolCommand {

16
  case class Args(summary: File = null, outputDir: File = null, pageArgs: Map[String, String] = Map()) extends AbstractArgs
17
18
19
20
21
22
23
24

  class OptParser extends AbstractOptParser {
    opt[File]('s', "summary") required () maxOccurs (1) valueName ("<file>") action { (x, c) =>
      c.copy(summary = x)
    }
    opt[File]('o', "outputDir") required () maxOccurs (1) valueName ("<file>") action { (x, c) =>
      c.copy(outputDir = x)
    }
25
26
27
    opt[Map[String, String]]('a', "args") action { (x, c) =>
      c.copy(pageArgs = c.pageArgs ++ x)
    }
28
29
30
31
32
33
34
35
  }

  private var setSummary: Summary = _

  final def summary = setSummary

  def pageArgs: Map[String, Any] = Map()

Peter van 't Hof's avatar
Peter van 't Hof committed
36
37
38
  private var done = 0
  private var total = 0

39
40
41
42
43
44
45
46
47
  def main(args: Array[String]): Unit = {
    logger.info("Start")

    val argsParser = new OptParser
    val cmdArgs: Args = argsParser.parse(args, Args()) getOrElse sys.exit(1)

    require(cmdArgs.outputDir.exists(), "Output dir does not exist")
    require(cmdArgs.outputDir.isDirectory, "Output dir is not a directory")

Peter van 't Hof's avatar
Peter van 't Hof committed
48
    logger.info("Write Base files")
49
    // Write css to output dir
50
    val cssDir = new File(cmdArgs.outputDir, "css")
51
52
    cssDir.mkdirs()
    val cssWriter = new PrintWriter(new File(cssDir, "biopet.css"))
53
    Source.fromInputStream(getClass.getResourceAsStream("/nl/lumc/sasc/biopet/core/report/biopet.css")).getLines().foreach(cssWriter.println(_))
54
55
    cssWriter.close()

Peter van 't Hof's avatar
Peter van 't Hof committed
56
    logger.info("Parsing summary")
57
58
    setSummary = new Summary(cmdArgs.summary)

Peter van 't Hof's avatar
Peter van 't Hof committed
59
60
61
    total = countPages(indexPage)
    logger.info(total + " pages to be generated")

Peter van 't Hof's avatar
Peter van 't Hof committed
62
    logger.info("Generate pages")
63
    generatePage(summary, indexPage, cmdArgs.outputDir,
64
65
      args = pageArgs ++ cmdArgs.pageArgs ++
        Map("summary" -> summary, "reportName" -> reportName, "indexPage" -> indexPage))
66

Peter van 't Hof's avatar
Peter van 't Hof committed
67
    logger.info(done + " Done")
68
69
70
71
72
73
  }

  def indexPage: ReportPage

  def reportName: String

Peter van 't Hof's avatar
Peter van 't Hof committed
74
75
76
77
  def countPages(page: ReportPage): Int = {
    page.subPages.map(x => countPages(x._2)).fold(1)(_ + _)
  }

78
79
80
81
82
83
  def generatePage(summary: Summary,
                   page: ReportPage,
                   outputDir: File,
                   path: List[String] = Nil,
                   args: Map[String, Any] = Map()): Unit = {

Peter van 't Hof's avatar
Peter van 't Hof committed
84
85
    val pageOutputDir = new File(outputDir, path.mkString(File.separator))
    pageOutputDir.mkdirs()
86
87
88
89
90
91
92
    val rootPath = "./" + Array.fill(path.size)("../").mkString("")
    val pageArgs = args ++ page.args ++
      Map("page" -> page,
        "path" -> path,
        "outputDir" -> pageOutputDir,
        "rootPath" -> rootPath
      )
93

Peter van 't Hof's avatar
Peter van 't Hof committed
94
95
96
97
    val output = ReportBuilder.renderTemplate("/nl/lumc/sasc/biopet/core/report/main.ssp",
      pageArgs ++ Map("args" -> pageArgs))

    val file = new File(pageOutputDir, "index.html")
98
99
100
101
102
    val writer = new PrintWriter(file)
    writer.println(output)
    writer.close()

    // Generating subpages
103
    for ((name, subPage) <- page.subPages.par) {
104
105
      generatePage(summary, subPage, outputDir, path ::: name :: Nil, pageArgs)
    }
Peter van 't Hof's avatar
Peter van 't Hof committed
106
107
    done += 1
    if (done % 100 == 0) logger.info(done + " Done, " + (done.toDouble / total * 100) + "%")
108
109
  }
}
Peter van 't Hof's avatar
Peter van 't Hof committed
110
111
112
113
114

object ReportBuilder {

  protected val engine = new TemplateEngine()

115
  def renderTemplate(location: String, args: Map[String, Any]): String = {
116
    engine.layout(TemplateSource.fromFile(getClass.getResource(location).getPath), args)
Peter van 't Hof's avatar
Peter van 't Hof committed
117
118
  }
}