Browse Source

Fix sections order and generate multiple reports

Outputs all reports as HTML in the same given folder.
master
Matt Baer 8 years ago
parent
commit
38a2c39509
3 changed files with 89 additions and 94 deletions
  1. +9
    -51
      lifereport.go
  2. +38
    -10
      lifereport/report.go
  3. +42
    -33
      reports/template.json

+ 9
- 51
lifereport.go View File

@@ -18,9 +18,9 @@ type (
Report struct {
Num int
Month string
Year int `json:"year"`
Summary string `json:"summary"`
Sections []Section
Year int `json:"year"`
Summary string `json:"summary"`
Sections []Section `json:"sections"`
}

// 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
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
// NNN-month.json
baseName := path.Base(f.Name())
@@ -58,53 +64,5 @@ func ParseReport(f *os.File) (*Report, error) {
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
}

+ 38
- 10
lifereport/report.go View File

@@ -3,8 +3,10 @@ package main
import (
"fmt"
"html/template"
"io/ioutil"
"os"
"path"
"strings"

report "github.com/thebaer/life-report"
)
@@ -18,23 +20,49 @@ func main() {
}

dir := os.Args[1]
f, err := os.Open(path.Join(dir, "template.json"))
files, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Fprintf(os.Stdout, "Unable to open file: %v\n", err)
fmt.Print("Unable to read directory: %v\n", err)
return
}

r, err := report.ParseReport(f)
t, err := template.ParseFiles("../report.tmpl")
if err != nil {
fmt.Fprintf(os.Stdout, "Unable to parse report: %v\n", err)
fmt.Printf("Unable to parse template: %v\n", err)
return
}
f.Close()

t, err := template.ParseFiles("../report.tmpl")
if err != nil {
fmt.Fprintf(os.Stdout, "Unable to parse template: %v\n", err)
return
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()
}
t.Execute(os.Stdout, r)
}

+ 42
- 33
reports/template.json View File

@@ -1,36 +1,45 @@
{
"year": 2016,
"health": {
"title": "health / diet",
"details": [
]
},
"money": {
"summary": [
]
},
"travels": {
"details": [
]
},
"studies": {
"details": [
]
},
"music": {
"details": [
]
},
"books": {
"details": [
]
},
"distractions": {
"details": [
]
},
"projects": {
"details": [
]
}
"sections": [
{
"title": "health / diet",
"details": [
]
},
{
"title": "money",
"summary": [
]
},
{
"title": "travels",
"details": [
]
},
{
"title": "studies",
"details": [
]
},
{
"title": "music",
"details": [
]
},
{
"title": "books",
"details": [
]
},
{
"title": "distractions",
"details": [
]
},
{
"title": "work / projects",
"details": [
]
}
]
}

Loading…
Cancel
Save