Skip to content

Commit 6b1d6a0

Browse files
committed
Merge branch 'fwslash/download-command'
2 parents 79f0f41 + a013b6b commit 6b1d6a0

5 files changed

Lines changed: 102 additions & 7 deletions

File tree

api/api.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,32 @@ func Fetch(url string) ([]*Problem, error) {
6060
return payload.Problems, nil
6161
}
6262

63+
func Download(url string) (*Submission, error) {
64+
req, err := http.NewRequest("GET", url, nil)
65+
if err != nil {
66+
return nil, err
67+
}
68+
69+
res, err := http.DefaultClient.Do(req)
70+
if err != nil {
71+
return nil, err
72+
}
73+
defer res.Body.Close()
74+
75+
payload := &PayloadSubmission{}
76+
dec := json.NewDecoder(res.Body)
77+
err = dec.Decode(payload)
78+
if err != nil {
79+
return nil, fmt.Errorf("error parsing API response - %s", err)
80+
}
81+
82+
if res.StatusCode != http.StatusOK {
83+
return nil, fmt.Errorf(`unable to fetch Submission (HTTP: %d) - %s`, res.StatusCode, payload.Error)
84+
}
85+
86+
return payload.Submission, err
87+
}
88+
6389
// Demo fetches the first problem in each language track.
6490
func Demo(c *config.Config) ([]*Problem, error) {
6591
url := fmt.Sprintf("%s/problems/demo?key=%s", c.XAPI, c.APIKey)

api/submission.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package api
22

33
// Submission is an iteration that has been submitted to the API.
44
type Submission struct {
5-
URL string `json:"url"`
6-
TrackID string `json:"track_id"`
7-
Language string `json:"language"`
8-
Slug string `json:"slug"`
9-
Name string `json:"name"`
5+
URL string `json:"url"`
6+
TrackID string `json:"track_id"`
7+
Language string `json:"language"`
8+
Slug string `json:"slug"`
9+
Name string `json:"name"`
10+
Username string `json:"username"`
11+
ProblemFiles map[string]string `json:"problem_files"`
12+
SolutionFiles map[string]string `json:"solution_files"`
1013
}

bin/build

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
22

3-
set -e
4-
53
go build -o out/exercism exercism/main.go
4+
5+
set -e

cmd/download.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"log"
7+
"os"
8+
"path/filepath"
9+
10+
"github.com/codegangsta/cli"
11+
"github.com/exercism/cli/api"
12+
"github.com/exercism/cli/config"
13+
)
14+
15+
// Download returns specified submissions and related problem.
16+
func Download(ctx *cli.Context) {
17+
c, err := config.Read(ctx.GlobalString("config"))
18+
if err != nil {
19+
log.Fatal(err)
20+
}
21+
22+
args := ctx.Args()
23+
24+
if len(args) != 1 {
25+
msg := "Usage: exercism download SUBMISSION_ID"
26+
log.Fatal(msg)
27+
}
28+
29+
var url string
30+
url = fmt.Sprintf("%s/api/v1/submissions/%s", c.API, args[0])
31+
32+
submission, err := api.Download(url)
33+
if err != nil {
34+
log.Fatal(err)
35+
}
36+
37+
var path string
38+
39+
path = filepath.Join(c.Dir, "solutions", submission.Username, submission.Language, submission.Slug, args[0])
40+
41+
if err := os.MkdirAll(path, 0755); err != nil {
42+
log.Fatal(err)
43+
}
44+
45+
for name, contents := range submission.ProblemFiles {
46+
if err := ioutil.WriteFile(fmt.Sprintf("%s/%s", path, name), []byte(contents), 0755); err != nil {
47+
log.Fatal(err)
48+
}
49+
}
50+
51+
for name, contents := range submission.SolutionFiles {
52+
if err := ioutil.WriteFile(fmt.Sprintf("%s/%s", path, name), []byte(contents), 0755); err != nil {
53+
log.Fatal(err)
54+
}
55+
}
56+
57+
fmt.Printf("Successfully downloaded submission.\n\nThe submission can be viewed at:\n %s\n\n", path)
58+
59+
}

exercism/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const (
3030
descLogout = "DEPRECATED: Clear exercism.io api credentials"
3131

3232
descLongRestore = "Restore will pull the latest revisions of exercises that have already been submitted. It will *not* overwrite existing files. If you have made changes to a file and have not submitted it, and you're trying to restore the last submitted version, first move that file out of the way, then call restore."
33+
descDownload = "Downloads and saves a specified submission into the local system"
3334
)
3435

3536
func main() {
@@ -123,6 +124,12 @@ func main() {
123124
Usage: descTracks,
124125
Action: cmd.Tracks,
125126
},
127+
{
128+
Name: "download",
129+
ShortName: "dl",
130+
Usage: descDownload,
131+
Action: cmd.Download,
132+
},
126133
}
127134
if err := app.Run(os.Args); err != nil {
128135

0 commit comments

Comments
 (0)