Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 61 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,73 @@

Classeviva is a Go library and CLI tool to access the popular school portal https://web.spaggiari.eu.

## Grades

Text output:

```text
$ classeviva grades list --limit 3
+------------+-------+-----------------+-------------------------------+
| DATE | GRADE | SUBJECT | NOTES |
+------------+-------+-----------------+-------------------------------+
| 2022-04-27 | 9 | ARTE E IMMAGINE | |
| 2022-04-22 | 7+ | COMPORTAMENTO | comportamento della settimana |
| | 7 | SCIENZE | |
+------------+-------+-----------------+-------------------------------+%
```

JSON output:

```shell
$ classeviva grades list --limit 1
$ classeviva grades list --limit 1 --format json
[
{
"subjectDesc": "MUSICA",
"evtDate": "2022-04-20",
"subjectDesc": "ARTE E IMMAGINE",
"evtDate": "2022-04-27",
"decimalValue": 9,
"displayValue": "9",
"color": "green",
"skillValueDesc": " Innovazioni musicali. Dalla Camerata fiorentina all'opera lirica.",
"notesForFamily": ""
"skillValueDesc": " "
}
]
```

## Agenda

Text output:

```text
$ classeviva agenda list --limit 2
+---------------------------+---------------------------+---------+----------------------+-----------------------------------------------------------------------+
| BEGIN | END | SUBJECT | TEACHER | NOTES |
+---------------------------+---------------------------+---------+----------------------+-----------------------------------------------------------------------+
| 2022-05-02T09:00:00+02:00 | 2022-05-02T10:00:00+02:00 | | PESANDO MARGHERITA | Inizio interrogazioni di inglese (1º turno) |
| 2022-05-03T00:00:00+02:00 | 2022-05-03T23:59:59+02:00 | | AVANZATO PAOLA CARLA | Link per colloqui |
+---------------------------+---------------------------+---------+----------------------+-----------------------------------------------------------------------+
```

JSON output:

```text
$ classeviva agenda list --until 2022-04-27 --limit 2
[
{
"evtId": 546249,
"evtCode": "AGNT",
"evtDatetimeBegin": "2022-05-02T09:00:00+02:00",
"evtDatetimeEnd": "2022-05-02T10:00:00+02:00",
"notes": "Inizio interrogazioni di inglese (1º turno)",
"authorName": "PESANDO MARGHERITA",
"subjectDesc": ""
},
{
"evtId": 578930,
"evtCode": "AGNT",
"evtDatetimeBegin": "2022-05-03T00:00:00+02:00",
"evtDatetimeEnd": "2022-05-03T23:59:59+02:00",
"notes": "Link per colloqui prof. AVANZATO",
"authorName": "AVANZATO PAOLA CARLA",
"subjectDesc": ""
}
]
```
25 changes: 25 additions & 0 deletions adapters/feedback/exported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package feedback

var (
fb = Default()
)

func SetDefault(f *Feedback) {
fb = f
}

func SetFormat(format OutputFormat) {
fb.SetFormat(format)
}

func Println(v interface{}) {
fb.Println(v)
}

func Error(v interface{}) {
fb.Error(v)
}

func PrintResult(result Result) (err error) {
return fb.PrintResult(result)
}
50 changes: 45 additions & 5 deletions adapters/feedback/feedback.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
package feedback

import (
"encoding/json"
"fmt"
"io"
"os"
)

const (
Text OutputFormat = iota
JSON
)

type OutputFormat int

type Feedback struct {
out io.Writer
err io.Writer
out io.Writer
err io.Writer
format OutputFormat
}

func New(out, err io.Writer) *Feedback {
return &Feedback{out: out, err: err}
func New(out, err io.Writer, format OutputFormat) *Feedback {
return &Feedback{out: out, err: err, format: format}
}

func Default() *Feedback {
return New(os.Stdout, os.Stderr)
return New(os.Stdout, os.Stderr, Text)
}

func (fb *Feedback) SetFormat(format OutputFormat) {
fb.format = format
}

func (fb *Feedback) Println(v interface{}) {
Expand All @@ -26,3 +39,30 @@ func (fb *Feedback) Println(v interface{}) {
func (fb *Feedback) Error(v interface{}) {
fmt.Fprintln(fb.err, v)
}

func (fb *Feedback) PrintResult(result Result) error {
var output string

switch fb.format {
case JSON:
byteOutput, err := json.MarshalIndent(result.Data(), "", " ")
if err != nil {
return fmt.Errorf("failed to marshall result: %w", err)
}
output = string(byteOutput)
default:
output = result.String()
}

_, err := fmt.Fprint(fb.out, output)
if err != nil {
return fmt.Errorf("failed to print result: %w", err)
}

return nil
}

type Result interface {
fmt.Stringer
Data() interface{}
}
108 changes: 104 additions & 4 deletions adapters/feedback/feedback_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ import (

"github.com/stretchr/testify/assert"
"github.com/zmoog/classeviva/adapters/feedback"
"github.com/zmoog/classeviva/adapters/spaggiari"
"github.com/zmoog/classeviva/commands"
)

func TestPrint(t *testing.T) {

t.Run("Println message to standard output", func(t *testing.T) {
stdout := bytes.Buffer{}
stderr := bytes.Buffer{}
fb := feedback.New(&stdout, &stderr)
fb := feedback.New(&stdout, &stderr, feedback.Text)
feedback.SetDefault(fb)

fb.Println("welcome to this f* world!")
feedback.Println("welcome to this f* world!")

assert.Equal(t, "welcome to this f* world!\n", stdout.String())
assert.Equal(t, "", stderr.String())
Expand All @@ -26,11 +29,108 @@ func TestError(t *testing.T) {
t.Run("Print message to standard error", func(t *testing.T) {
stdout := bytes.Buffer{}
stderr := bytes.Buffer{}
fb := feedback.New(&stdout, &stderr)
fb := feedback.New(&stdout, &stderr, feedback.Text)
feedback.SetDefault(fb)

fb.Error("Doh!")
feedback.Error("Doh!")

assert.Equal(t, "", stdout.String())
assert.Equal(t, "Doh!\n", stderr.String())
})
}

func TestPrintResult(t *testing.T) {

t.Run("Print result in plain text", func(t *testing.T) {
stdout := bytes.Buffer{}
stderr := bytes.Buffer{}
fb := feedback.New(&stdout, &stderr, feedback.Text)
feedback.SetDefault(fb)

grades := []spaggiari.Grade{
{
Subject: "COMPORTAMENTO",
Date: "2022-04-22",
DecimalValue: 7.25,
DisplaylValue: "7+",
Color: "green",
Notes: "comportamento della settimana",
},
{
Subject: "SCIENZE",
Date: "2022-04-22",
DecimalValue: 7,
DisplaylValue: "7",
Color: "green",
Description: " orale",
},
}

err := feedback.PrintResult(commands.GradesResult{
Grades: grades,
})
assert.NoError(t, err)

assert.Equal(t,
"+------------+-------+---------------+-------------------------------+\n"+
"| DATE | GRADE | SUBJECT | NOTES |\n"+
"+------------+-------+---------------+-------------------------------+\n"+
"| 2022-04-22 | \x1b[32m7+\x1b[0m | COMPORTAMENTO | comportamento della settimana |\n"+
"| | \x1b[32m7\x1b[0m | SCIENZE | |\n"+
"+------------+-------+---------------+-------------------------------+",
stdout.String(),
)
assert.Equal(t, "", stderr.String())
})

t.Run("Print result in JSON", func(t *testing.T) {
stdout := bytes.Buffer{}
stderr := bytes.Buffer{}
fb := feedback.New(&stdout, &stderr, feedback.JSON)
feedback.SetDefault(fb)

grades := []spaggiari.Grade{
{
Subject: "COMPORTAMENTO",
Date: "2022-04-22",
DecimalValue: 7.25,
DisplaylValue: "7+",
Color: "green",
Notes: "comportamento della settimana",
},
{
Subject: "SCIENZE",
Date: "2022-04-22",
DecimalValue: 7,
DisplaylValue: "7",
Color: "green",
Description: " orale",
},
}

err := feedback.PrintResult(commands.GradesResult{
Grades: grades,
})
assert.NoError(t, err)

assert.Equal(t, `[
{
"subjectDesc": "COMPORTAMENTO",
"evtDate": "2022-04-22",
"decimalValue": 7.25,
"displayValue": "7+",
"color": "green",
"notesForFamily": "comportamento della settimana"
},
{
"subjectDesc": "SCIENZE",
"evtDate": "2022-04-22",
"decimalValue": 7,
"displayValue": "7",
"color": "green",
"skillValueDesc": " orale"
}
]`, stdout.String())
assert.Equal(t, "", stderr.String())
})
}
5 changes: 3 additions & 2 deletions adapters/spaggiari/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func (c spaggiariAdapter) List() ([]Grade, error) {
if err != nil {
return []Grade{}, err
}
log.Trace(string(body))

envelope := map[string][]Grade{}

Expand All @@ -98,8 +99,7 @@ func (c spaggiariAdapter) ListAgenda(since, until time.Time) ([]AgendaEntry, err
_until := until.Format("20060102")

url := baseUrl + "/students/" + identity.ID + "/agenda/all/" + _since + "/" + _until
// fmt.Println(url)
log.Debug(url)
log.Trace(string(url))

req, err := c.newRequest("GET", url, nil, identity)
if err != nil {
Expand All @@ -120,6 +120,7 @@ func (c spaggiariAdapter) ListAgenda(since, until time.Time) ([]AgendaEntry, err
if err != nil {
return []AgendaEntry{}, err
}
log.Trace(string(body))

envelope := map[string][]AgendaEntry{}

Expand Down
3 changes: 1 addition & 2 deletions adapters/spaggiari/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,7 @@ func (f IdentityFetcher) Fetch() (Identity, error) {
if err != nil {
return Identity{}, err
}

log.Debug(string(body))
log.Trace(string(body))

identity := Identity{}

Expand Down
4 changes: 2 additions & 2 deletions adapters/spaggiari/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ type Grade struct {
DecimalValue float32 `json:"decimalValue"`
DisplaylValue string `json:"displayValue"`
Color string `json:"color"`
Description string `json:"skillValueDesc"`
Notes string `json:"notesForFamily"`
Description string `json:"skillValueDesc,omitempty"`
Notes string `json:"notesForFamily,omitempty"`
}

type AgendaEntry struct {
Expand Down
Loading