]> gitweb @ CieloNegro.org - task-reporter.git/commitdiff
new tsv
authorPHO <pho@cielonegro.org>
Fri, 10 Oct 2014 03:48:18 +0000 (12:48 +0900)
committerPHO <pho@cielonegro.org>
Fri, 10 Oct 2014 03:48:18 +0000 (12:48 +0900)
build.sbt
src/main/scala/jp/ymir/taskReporter/core/Report.scala
src/main/scala/jp/ymir/taskReporter/core/ReportSet.scala
src/main/scala/jp/ymir/taskReporter/core/TSV.scala [new file with mode: 0644]
src/main/scala/jp/ymir/taskReporter/core/Task.scala

index f92aaa87e6f303bb8d318da8628336eccefd1a22..922e0eeeeedbe74cdc6aafb554871ac1e73f90fd 100644 (file)
--- a/build.sbt
+++ b/build.sbt
@@ -8,11 +8,11 @@ libraryDependencies <+=
 libraryDependencies +=
   "org.scala-tools.sbinary" %% "sbinary" % "0.4.2"
 
-/* There is also manual dependencies in ./lib:
- *
- * - JCalendar <http://toedter.com/jcalendar/>
- */
+// There is also manual dependencies in ./lib:
+//
+// - JCalendar <http://toedter.com/jcalendar/>
+//
 
-scalacOptions ++= Seq("-deprecation", "-unchecked", "-encoding", "UTF-8")
+scalacOptions ++= Seq("-deprecation", "-unchecked", "-encoding", "UTF-8", "-feature")
 
 assemblySettings
index e147e66b8fac731c72cf82824d0db29c0aa7bb36..1963b6c799784f401fe0f1d428479ea02e5f5719 100644 (file)
@@ -35,22 +35,22 @@ class Report(private val _date: Calendar) extends AbstractTableModel {
     column match {
       case 0 => "チケットID"
       case 1 => "作業名"
-      case 2 => "ä»®æ\9c\9fé\99\90"
-      case 3 => "期限"
+      case 2 => "ä½\9c業å®\8cäº\86äº\88å®\9aå¹´æ\9c\88æ\97¥"
+      case 3 => "タスク期限"
       case 4 => "状態"
-      case 5 => "è£\9c足"
+      case 5 => "説æ\98\8e"
     }
   }
 
   def getValueAt(row: Int, column: Int) : Object = {
     val task = _tasks(row)
     column match {
-      case 0 => task.ticketID : Integer
+      case 0 => task.ticketID.map(_.toString).getOrElse("")
       case 1 => task.title
-      case 2 => task.tentativeDeadline.map(dateString).getOrElse("")
-      case 3 => task.deadline         .map(dateString).getOrElse("")
+      case 2 => dateString(task.expectedCompletionDate)
+      case 3 => task.deadline.map(dateString).getOrElse("")
       case 4 => task.status
-      case 5 => task.supplement
+      case 5 => task.description.getOrElse("")
     }
   }
 }
index 6285589f88569f0350c0f5b7e946558769816365..66a5d6d08fdf90a79991b8a33adaff6ba2094eae 100644 (file)
@@ -16,9 +16,23 @@ class ReportSet(private var _file: Option[File])
   _file.foreach { file => load(file) }
 
   def load(file: File) {
+    import Task._
+
     var reports = _reports.empty
     val src     = Source.fromFile(file, "UTF-8")
 
+    TSV.decode(src.mkString).foreach { task =>
+      if (reports.isDefinedAt(task.date)) {
+        reports(task.date) += task
+      }
+      else {
+        val report = new Report(task.date)
+        report  += task
+        reports += (report.date -> report)
+      }
+    }
+
+/*
     for (line <- src.getLines) {
       if (!line.isEmpty) {
         val task = new Task(line)
@@ -32,6 +46,7 @@ class ReportSet(private var _file: Option[File])
         }
       }
     }
+ */
 
     _file    = Some(file)
     _reports = reports
diff --git a/src/main/scala/jp/ymir/taskReporter/core/TSV.scala b/src/main/scala/jp/ymir/taskReporter/core/TSV.scala
new file mode 100644 (file)
index 0000000..28d9833
--- /dev/null
@@ -0,0 +1,56 @@
+package jp.ymir.taskReporter.core
+import scala.collection._
+import scala.collection.immutable.StringLike
+
+object TSV {
+  type Header = Seq[Symbol]
+  type Field  = String
+  type Record = Map[Symbol, Field]
+
+  def decode[A: FromRecord](tsv: StringLike[_]): Seq[A] = {
+    val lines  = tsv.split('\n').filter(!_.isEmpty)
+    val header = lines.head.split('\t').map(Symbol(_))
+    val body   = lines.tail.map(line => (header zip line.split('\t')).toMap)
+    return body.map(implicitly[FromRecord[A]].parseRecord)
+  }
+
+  trait FromRecord[A] {
+    def parseRecord(r: Record): A
+  }
+
+  trait FromField[A] {
+    def parseField(f: Field): A
+  }
+  def parseField[A: FromField](f: Field): A
+    = implicitly[FromField[A]].parseField(f)
+
+  trait ToRecord[A] {
+    def toRecord(a: A): Record
+  }
+
+  trait ToField[A] {
+    def toField(a: A): Field
+  }
+
+  // Option[A]
+  implicit def OptionFromField[A: FromField] = new FromField[Option[A]] {
+    def parseField(f: Field): Option[A] = {
+      if (f.isEmpty) {
+        return None
+      }
+      else {
+        return Some(implicitly[FromField[A]].parseField(f))
+      }
+    }
+  }
+
+  // String
+  implicit def StringFromField = new FromField[String] {
+    def parseField(f: Field): String = f
+  }
+
+  // Int
+  implicit def IntFromField = new FromField[Int] {
+    def parseField(f: Field): Int = f.toInt
+  }
+}
index 7b38e0a8013f8ddbecf77d0b1e64c87642d2b7a6..53e813d7b0c5079bed38816c010f5cc9be1c02c5 100644 (file)
@@ -3,6 +3,63 @@ import java.util.Calendar
 import java.util.GregorianCalendar
 import scala.util.matching.Regex
 
+case class Task(
+  date:                   Calendar,
+  ticketID:               Option[Int],
+  title:                  String,
+  expectedCompletionDate: Calendar,
+  deadline:               Option[Calendar],
+  status:                 Task.Status,
+  description:            Option[String]
+)
+
+object Task {
+  import TSV._
+
+  sealed abstract class Status
+  object Status {
+    case object DoingFine extends Status
+    case object Lagging extends Status
+    case object DeadlineChanged extends Status
+    case object Completed extends Status
+  }
+
+  implicit def CalendarFromField = new FromField[Calendar] {
+    val pattern = """^(\d{4})/(\d{2})/(\d{2})$""".r
+
+    def parseField(f: Field): Calendar = {
+      f match {
+        case pattern(year, month, day) =>
+          new GregorianCalendar(year.toInt, month.toInt, day.toInt)
+      }
+    }
+  }
+
+  implicit def StatusFromField = new FromField[Status] {
+    def parseField(f: Field): Status = f match {
+      case "順調"     => Status.DoingFine
+      case "遅延"     => Status.Lagging
+      case "期限変更" => Status.DeadlineChanged
+      case "完了"     => Status.Completed
+    }
+  }
+
+  implicit def TaskFromRecord = new FromRecord[Task] {
+    def parseRecord(r: Record): Task = {
+      return Task(
+        date                   = parseField[Calendar](r('報告日)),
+        ticketID               = parseField[Option[Int]](r('チケットID)),
+        title                  = parseField[String](r('作業名)),
+        expectedCompletionDate = parseField[Calendar](r('作業完了予定年月日)),
+        deadline               = parseField[Option[Calendar]](r('タスク期限)),
+        status                 = parseField[Status](r('状態)),
+        description            = parseField[Option[String]](r('説明))
+      )
+    }
+  }
+}
+
+/*
 class Task(tsvLine: String) {
   sealed abstract class Status
   object Status {
@@ -88,3 +145,4 @@ class Task(tsvLine: String) {
     }
   }
 }
+ */