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
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