Skip to content

Commit

Permalink
Merge pull request sequelize#155 from Tonkpils/fetch-output
Browse files Browse the repository at this point in the history
Display problems that have not yet been submitted
  • Loading branch information
Tonkpils committed Jan 30, 2015
2 parents 5c3366b + 31521c8 commit a6ac2c8
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The exercism CLI follows [semantic versioning](http://semver.org/).
* [#153](https://github.com/exercism/cli/pull/153): Refactored configuration package - [@kytrinyx](https://github.com/kytrinyx)
* [#154](https://github.com/exercism/cli/pull/154): Add 'list' command to list available exercises for a language - [@lcowell](https://github.com/lcowell)
* [#157](https://github.com/exercism/cli/pull/157): Refactored API package - [@Tonkpils](https://github.com/Tonkpils)
* [#155](https://github.com/exercism/cli/pull/155): Display problems not yet submitted on fetch API - [@Tonkpils](https://github.com/Tonkpils)
* **Your contribution here**

## v1.9.2 (2015-01-11)
Expand Down
30 changes: 26 additions & 4 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ type PayloadSubmission struct {
PayloadError
}

// SubmissionInfo contains state information about a submission.
type SubmissionInfo struct {
Slug string `json:"slug"`
State string `json:"state"`
}

// Fetch retrieves problems from the API.
// In most cases these problems consist of a test suite and a README
// from the x-api, but it is also used when restoring earlier iterations.
Expand Down Expand Up @@ -62,7 +68,7 @@ func (c *Client) Fetch(args []string) ([]*Problem, error) {
}

if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf(`unable to fetch problems (HTTP: %d) - %s`, res.StatusCode, payload.Error)
return nil, fmt.Errorf("unable to fetch problems (HTTP: %d) - %s", res.StatusCode, payload.Error)
}

return payload.Problems, nil
Expand All @@ -83,12 +89,28 @@ func (c *Client) Restore() ([]*Problem, error) {
}

if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf(`unable to fetch problems (HTTP: %d) - %s`, res.StatusCode, payload.Error)
return nil, fmt.Errorf("unable to fetch problems (HTTP: %d) - %s", res.StatusCode, payload.Error)
}

return payload.Problems, nil
}

// Submissions gets a list of submitted exercises and their current acceptance state.
func (c *Client) Submissions() (map[string][]SubmissionInfo, error) {
url := fmt.Sprintf("%s/api/v1/exercises?key=%s", c.APIHost, c.APIKey)
req, err := c.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}

var payload map[string][]SubmissionInfo
if _, err := c.Do(req, &payload); err != nil {
return nil, err
}

return payload, nil
}

// Download fetches a solution by submission key and writes it to disk.
func (c *Client) Download(submissionID string) (*Submission, error) {
url := fmt.Sprintf("%s/api/v1/submissions/%s", c.APIHost, submissionID)
Expand Down Expand Up @@ -126,7 +148,7 @@ func (c *Client) Demo() ([]*Problem, error) {
}

if res.StatusCode != http.StatusOK {
return nil, fmt.Errorf(`unable to fetch problems (HTTP: %d) - %s`, res.StatusCode, payload.Error)
return nil, fmt.Errorf("unable to fetch problems (HTTP: %d) - %s", res.StatusCode, payload.Error)
}

return payload.Problems, nil
Expand All @@ -152,7 +174,7 @@ func (c *Client) Submit(iter *Iteration) (*Submission, error) {
}

if res.StatusCode != http.StatusCreated {
return nil, fmt.Errorf(`unable to submit (HTTP: %d) - %s`, res.StatusCode, ps.Error)
return nil, fmt.Errorf("unable to submit (HTTP: %d) - %s", res.StatusCode, ps.Error)
}

return ps.Submission, nil
Expand Down
13 changes: 7 additions & 6 deletions api/problem.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import "fmt"

// Problem represents a specific problem in a given language track.
type Problem struct {
ID string `json:"id"`
TrackID string `json:"track_id"`
Language string `json:"language"`
Slug string `json:"slug"`
Name string `json:"name"`
Files map[string]string `json:"files"`
ID string `json:"id"`
TrackID string `json:"track_id"`
Language string `json:"language"`
Slug string `json:"slug"`
Name string `json:"name"`
Files map[string]string `json:"files"`
Submitted bool
}

func (p *Problem) String() string {
Expand Down
24 changes: 23 additions & 1 deletion cmd/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,32 @@ func Fetch(ctx *cli.Context) {
log.Fatal(err)
}

submissionInfo, err := client.Submissions()
if err != nil {
log.Fatal(err)
}

if err := setSubmissionState(problems, submissionInfo); err != nil {
log.Fatal(err)
}

hw := user.NewHomework(problems, c)
if err := hw.Save(); err != nil {
log.Fatal(err)
}

hw.Summarize()
hw.Summarize(user.HWAll)
}

func setSubmissionState(problems []*api.Problem, submissionInfo map[string][]api.SubmissionInfo) error {
for _, problem := range problems {
langSubmissions := submissionInfo[problem.Language]
for _, submission := range langSubmissions {
if submission.Slug == problem.Slug {
problem.Submitted = true
}
}
}

return nil
}
2 changes: 1 addition & 1 deletion cmd/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ func Restore(ctx *cli.Context) {
if err := hw.Save(); err != nil {
log.Fatal(err)
}
hw.Summarize()
hw.Summarize(user.HWNotSubmitted)
}
15 changes: 14 additions & 1 deletion user/homework.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import (
// HWFilter is used to categorize homework items.
type HWFilter int

// SummaryOption is an alias of HWFilter that allows
// selective display of summary items
type SummaryOption HWFilter

const (
// HWAll represents all items in the collection.
HWAll = iota
Expand All @@ -19,6 +23,9 @@ const (
// HWNew represents problems that did not yet exist on the
// user's filesystem.
HWNew
// HWNotSubmitted represents problems that have not been submitted
// for review.
HWNotSubmitted
)

// Homework is a collection of problems that were fetched from the APIs.
Expand Down Expand Up @@ -96,6 +103,8 @@ func (hw *Homework) heading(filter HWFilter, count int) {
status = "Updated:"
case HWNew:
status = "New:"
case HWNotSubmitted:
status = "Not Submitted:"
}
summary := fmt.Sprintf("%d %s", count, unit)
fmt.Printf(hw.template, status, summary)
Expand All @@ -112,10 +121,14 @@ func (hw *Homework) maxTitleWidth() int {
}

// Summarize prints a full report of new and updated items in the set.
func (hw *Homework) Summarize() {
func (hw *Homework) Summarize(summaryFilter SummaryOption) {
hw.Report(HWUpdated)
hw.Report(HWNew)

if summaryFilter != HWNotSubmitted {
hw.Report(HWNotSubmitted)
}

fresh := len(hw.ItemsMatching(HWNew))
updated := len(hw.ItemsMatching(HWUpdated))
unchanged := len(hw.Items) - updated - fresh
Expand Down
2 changes: 2 additions & 0 deletions user/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ func (it *Item) Matches(filter HWFilter) bool {
return it.isNew
case HWUpdated:
return it.isUpdated
case HWNotSubmitted:
return !it.Submitted
}
return true
}
Expand Down

0 comments on commit a6ac2c8

Please sign in to comment.