Fix sections order and generate multiple reports
Outputs all reports as HTML in the same given folder.
This commit is contained in:
parent
0e4c211104
commit
38a2c39509
@ -18,9 +18,9 @@ type (
|
|||||||
Report struct {
|
Report struct {
|
||||||
Num int
|
Num int
|
||||||
Month string
|
Month string
|
||||||
Year int `json:"year"`
|
Year int `json:"year"`
|
||||||
Summary string `json:"summary"`
|
Summary string `json:"summary"`
|
||||||
Sections []Section
|
Sections []Section `json:"sections"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section represents an area of life to report on. This contains a
|
// Section represents an area of life to report on. This contains a
|
||||||
@ -42,6 +42,12 @@ func ParseReport(f *os.File) (*Report, error) {
|
|||||||
var err error
|
var err error
|
||||||
r := Report{}
|
r := Report{}
|
||||||
|
|
||||||
|
// Parse JSON into a Report
|
||||||
|
jsonParser := json.NewDecoder(f)
|
||||||
|
if err = jsonParser.Decode(&r); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Determine report number and month from filename in the format
|
// Determine report number and month from filename in the format
|
||||||
// NNN-month.json
|
// NNN-month.json
|
||||||
baseName := path.Base(f.Name())
|
baseName := path.Base(f.Name())
|
||||||
@ -58,53 +64,5 @@ func ParseReport(f *os.File) (*Report, error) {
|
|||||||
r.Month = "First"
|
r.Month = "First"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse JSON into a map
|
|
||||||
var d map[string]interface{}
|
|
||||||
jsonParser := json.NewDecoder(f)
|
|
||||||
if err = jsonParser.Decode(&d); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate Report struct from the map
|
|
||||||
for k, v := range d {
|
|
||||||
// Handle consistent properties here, like year
|
|
||||||
if k == "year" {
|
|
||||||
r.Year = int(v.(float64))
|
|
||||||
continue
|
|
||||||
} else if k == "summary" {
|
|
||||||
r.Summary = v.(string)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// All other properties will be the names of sections. The property name
|
|
||||||
// will be used as the default title for any given section, unless
|
|
||||||
// overridden by the object's actual `title` property.
|
|
||||||
s := Section{
|
|
||||||
Title: k,
|
|
||||||
}
|
|
||||||
m := v.(map[string]interface{})
|
|
||||||
if m["title"] != nil {
|
|
||||||
s.Title = m["title"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate section summary
|
|
||||||
if m["summary"] != nil {
|
|
||||||
sums := m["summary"].([]interface{})
|
|
||||||
for _, sum := range sums {
|
|
||||||
s.Summary = append(s.Summary, template.HTML(sum.(string)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate section details
|
|
||||||
if m["details"] != nil {
|
|
||||||
dets := m["details"].([]interface{})
|
|
||||||
for _, det := range dets {
|
|
||||||
s.Details = append(s.Details, template.HTML(det.(string)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Sections = append(r.Sections, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
report "github.com/thebaer/life-report"
|
report "github.com/thebaer/life-report"
|
||||||
)
|
)
|
||||||
@ -18,23 +20,49 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dir := os.Args[1]
|
dir := os.Args[1]
|
||||||
f, err := os.Open(path.Join(dir, "template.json"))
|
files, err := ioutil.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stdout, "Unable to open file: %v\n", err)
|
fmt.Print("Unable to read directory: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := report.ParseReport(f)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stdout, "Unable to parse report: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
|
|
||||||
t, err := template.ParseFiles("../report.tmpl")
|
t, err := template.ParseFiles("../report.tmpl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stdout, "Unable to parse template: %v\n", err)
|
fmt.Printf("Unable to parse template: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.Execute(os.Stdout, r)
|
|
||||||
|
for _, file := range files {
|
||||||
|
if file.Name() == "template.json" || !strings.HasSuffix(file.Name(), ".json") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(path.Join(dir, file.Name()))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stdout, "Unable to open file: %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(file.Name(), ".") {
|
||||||
|
f.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := report.ParseReport(f)
|
||||||
|
if err != nil {
|
||||||
|
f.Close()
|
||||||
|
fmt.Fprintf(os.Stdout, "Unable to parse report %s: %v\n", file.Name(), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
outName := strings.Replace(file.Name(), ".json", ".html", 1)
|
||||||
|
o, err := os.Create(path.Join(dir, outName))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stdout, "Unable to write report %s: %v\n", outName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Execute(o, r)
|
||||||
|
o.Close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,45 @@
|
|||||||
{
|
{
|
||||||
"year": 2016,
|
"year": 2016,
|
||||||
"health": {
|
"sections": [
|
||||||
"title": "health / diet",
|
{
|
||||||
"details": [
|
"title": "health / diet",
|
||||||
]
|
"details": [
|
||||||
},
|
]
|
||||||
"money": {
|
},
|
||||||
"summary": [
|
{
|
||||||
]
|
"title": "money",
|
||||||
},
|
"summary": [
|
||||||
"travels": {
|
]
|
||||||
"details": [
|
},
|
||||||
]
|
{
|
||||||
},
|
"title": "travels",
|
||||||
"studies": {
|
"details": [
|
||||||
"details": [
|
]
|
||||||
]
|
},
|
||||||
},
|
{
|
||||||
"music": {
|
"title": "studies",
|
||||||
"details": [
|
"details": [
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"books": {
|
{
|
||||||
"details": [
|
"title": "music",
|
||||||
]
|
"details": [
|
||||||
},
|
]
|
||||||
"distractions": {
|
},
|
||||||
"details": [
|
{
|
||||||
]
|
"title": "books",
|
||||||
},
|
"details": [
|
||||||
"projects": {
|
]
|
||||||
"details": [
|
},
|
||||||
]
|
{
|
||||||
}
|
"title": "distractions",
|
||||||
|
"details": [
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "work / projects",
|
||||||
|
"details": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user