Skip to content

Commit b638a9a

Browse files
committed
Extract unsubmit handler
1 parent 25873dc commit b638a9a

File tree

3 files changed

+71
-71
lines changed

3 files changed

+71
-71
lines changed

api/api.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@ var (
1616
UserAgent string
1717
)
1818

19+
// PayloadError represents an error message from the API.
20+
type PayloadError struct {
21+
Error string `json:"error"`
22+
}
23+
1924
// PayloadProblems represents a response containing problems.
2025
type PayloadProblems struct {
2126
Problems []*Problem
22-
Error string `json:"error"`
27+
PayloadError
2328
}
2429

2530
// PayloadSubmission represents metadata about a successful submission.
2631
type PayloadSubmission struct {
2732
*Submission
28-
Error string `json:"error"`
33+
PayloadError
2934
}
3035

3136
// Fetch retrieves problems from the API.
@@ -105,3 +110,33 @@ func Submit(url string, iter *Iteration) (*Submission, error) {
105110

106111
return ps.Submission, nil
107112
}
113+
114+
// Unsubmit deletes a submission.
115+
func Unsubmit(url string) error {
116+
req, err := http.NewRequest("DELETE", url, nil)
117+
if err != nil {
118+
return err
119+
}
120+
req.Header.Set("User-Agent", UserAgent)
121+
122+
res, err := http.DefaultClient.Do(req)
123+
if err != nil {
124+
return err
125+
}
126+
defer res.Body.Close()
127+
128+
body, err := ioutil.ReadAll(res.Body)
129+
if err != nil {
130+
return err
131+
}
132+
133+
pe := &PayloadError{}
134+
err = json.Unmarshal(body, pe)
135+
if err != nil {
136+
return err
137+
}
138+
if res.StatusCode != http.StatusNoContent {
139+
return fmt.Errorf(`unable to unsubmit (HTTP: %d) - %s`, res.StatusCode, pe.Error)
140+
}
141+
return nil
142+
}

handlers/unsubmit.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package handlers
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/codegangsta/cli"
8+
"github.com/exercism/cli/api"
9+
"github.com/exercism/cli/config"
10+
)
11+
12+
// Unsubmit deletes an iteration from the api.
13+
// If no iteration is specified, the most recent iteration
14+
// is deleted.
15+
func Unsubmit(ctx *cli.Context) {
16+
c, err := config.Read(ctx.GlobalString("config"))
17+
if err != nil {
18+
log.Fatal(err)
19+
}
20+
21+
if !c.IsAuthenticated() {
22+
log.Fatal(msgPleaseAuthenticate)
23+
}
24+
25+
url := fmt.Sprintf("%s/api/v1/user/assignments?key=%s", c.API, c.APIKey)
26+
err = api.Unsubmit(url)
27+
if err != nil {
28+
log.Fatal(err)
29+
}
30+
fmt.Println("Your most recent submission was successfully deleted.")
31+
}

main.go

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package main
22

33
import (
4-
"encoding/json"
54
"fmt"
6-
"io/ioutil"
7-
"net/http"
5+
"log"
86
"os"
97
"runtime"
108

119
"github.com/codegangsta/cli"
1210
"github.com/exercism/cli/api"
13-
"github.com/exercism/cli/config"
1411
"github.com/exercism/cli/handlers"
1512
)
1613

@@ -21,8 +18,6 @@ const (
2118
// lot of things get out of hand.
2219
Version = "1.7.0"
2320

24-
msgPleaseAuthenticate = "You must be authenticated. Run `exercism configure --key=YOUR_API_KEY`."
25-
2621
descDebug = "Outputs useful debug information."
2722
descConfigure = "Writes config values to a JSON file."
2823
descDemo = "Fetches a demo problem for each language track on exercism.io."
@@ -115,72 +110,11 @@ func main() {
115110
Name: "unsubmit",
116111
ShortName: "u",
117112
Usage: descUnsubmit,
118-
Action: func(ctx *cli.Context) {
119-
c, err := config.Read(ctx.GlobalString("config"))
120-
if err != nil {
121-
fmt.Println(err)
122-
return
123-
}
124-
125-
if !c.IsAuthenticated() {
126-
fmt.Println(msgPleaseAuthenticate)
127-
return
128-
}
129-
130-
err = UnsubmitAssignment(c)
131-
if err != nil {
132-
fmt.Println(err)
133-
return
134-
}
135-
fmt.Println("The last submission was successfully deleted.")
136-
},
113+
Action: handlers.Unsubmit,
137114
},
138115
}
139116
err := app.Run(os.Args)
140117
if err != nil {
141-
fmt.Errorf("%v", err)
142-
os.Exit(1)
143-
}
144-
}
145-
146-
func UnsubmitAssignment(c *config.Config) error {
147-
path := "api/v1/user/assignments"
148-
149-
url := fmt.Sprintf("%s/%s?key=%s", c.API, path, c.APIKey)
150-
151-
req, err := http.NewRequest("DELETE", url, nil)
152-
if err != nil {
153-
return err
118+
log.Fatal(err)
154119
}
155-
156-
req.Header.Set("User-Agent", api.UserAgent)
157-
158-
resp, err := http.DefaultClient.Do(req)
159-
if err != nil {
160-
err = fmt.Errorf("Error destroying submission: [%v]", err)
161-
return err
162-
}
163-
164-
body, err := ioutil.ReadAll(resp.Body)
165-
resp.Body.Close()
166-
if err != nil {
167-
return err
168-
}
169-
170-
if resp.StatusCode != http.StatusNoContent {
171-
172-
var ur struct {
173-
Error string
174-
}
175-
176-
err = json.Unmarshal(body, &ur)
177-
if err != nil {
178-
return err
179-
}
180-
181-
err = fmt.Errorf("Status: %d, Error: %v", resp.StatusCode, ur.Error)
182-
return err
183-
}
184-
185-
return nil
186120
}

0 commit comments

Comments
 (0)