Skip to content

Commit

Permalink
Implemented deleting entry
Browse files Browse the repository at this point in the history
  • Loading branch information
aQaTL committed May 5, 2018
1 parent d6ca141 commit 4b076c0
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 19 deletions.
32 changes: 32 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ func main() {
UsageText: "mal cmpl",
Action: setEntryStatusCompleted,
},
cli.Command{
Name: "delete",
Aliases: []string{"del"},
Category: "Update",
Usage: "Delete entry from your list",
UsageText: "mal delete",
Action: deleteEntry,
},
cli.Command{
Name: "sel",
Aliases: []string{"select"},
Expand Down Expand Up @@ -447,6 +455,30 @@ func setEntryStatusCompleted(ctx *cli.Context) error {
return nil
}

func deleteEntry(ctx *cli.Context) error {
c, list, err := loadMAL(ctx)
if err != nil {
return err
}
cfg := LoadConfig()

entry := list.GetByID(cfg.SelectedID)
if entry == nil {
return fmt.Errorf("no entry selected")
}

if ok := c.Delete(entry); !ok {
return fmt.Errorf("deleting entry failed")
}

title := color.HiRedString("%s", entry.Title)
fmt.Printf("%s seleted successfully\n", title)
list = list.DeleteByID(entry.ID)
cacheList(list)

return nil
}

func selectEntry(ctx *cli.Context) error {
switch {
case ctx.Bool("id"):
Expand Down
21 changes: 21 additions & 0 deletions mal/animelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,24 @@ func (list AnimeList) FilterByStatus(status MyStatus) AnimeList {
return filter(list, func(anime *Anime) bool { return anime.MyStatus == status })
}
}

func (list AnimeList) DeleteByID(id int) AnimeList {
idx := 0
found := false
for i, entry := range list {
if entry.ID == id {
idx = i
found = true
break
}
}
if !found {
return list
}

copy(list[idx:], list[idx+1:])
list[len(list)-1] = nil
list = list[:len(list)-1]

return list
}
76 changes: 57 additions & 19 deletions mal/mal.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
//For using as a printf format
const (
UpdateEndpoint = ApiEndpoint + "/animelist/update/%d.xml" //%d - anime database ID
DeleteEndpoint = ApiEndpoint + "/animelist/delete/%d.xml" //%d - anime database ID

UserAnimeListEndpoint = BaseMALAddress + "/malappinfo.php?u=%s&status=%s&type=anime" //%s - username %s - status

Expand Down Expand Up @@ -125,48 +126,85 @@ func (c *Client) AnimeList(status MyStatus) []*Anime {
}

func (c *Client) Update(entry *Anime) bool {
buf := &bytes.Buffer{}

template.Must(
template.New("animeXML").
Parse(AnimeXMLTemplate)).
Execute(buf, entry)

payload := url.Values{}
payload.Set("data", buf.String())

req, err := http.NewRequest(
http.MethodPost,
resp, err := c.doApiRequestWithEntryData(
fmt.Sprintf(UpdateEndpoint, entry.ID),
strings.NewReader(payload.Encode()),
http.MethodPost,
entry,
)
if err != nil {
log.Print(err)
return false
}

bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("Error creating http request: %v", err)
log.Printf("Error reading body: %v", err)
}
body := string(bodyBytes)

if body != "Updated" || resp.StatusCode != 200 {
log.Printf("Body: %v\nStatus: %s", body, resp.Status)
return false
}
req.Header.Set("Authorization", c.credentials)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return true
}

resp, err := http.DefaultClient.Do(req)
func (c *Client) Delete(entry *Anime) bool {
resp, err := c.doApiRequestWithEntryData(
fmt.Sprintf(DeleteEndpoint, entry.ID),
http.MethodPost,
entry,
)
if err != nil {
log.Printf("Error getting response for %d - %s update: %v", entry.ID, entry.Title, err)
log.Print(err)
return false
}

bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("Error reading body: %v", err)
return false
}
body := string(bodyBytes)

if body != "Updated" || resp.StatusCode != 200 {
if body != "Deleted" || resp.StatusCode != 200 {
log.Printf("Body: %v\nStatus: %s", body, resp.Status)
return false
}
return true
}

func (c *Client) doApiRequestWithEntryData(address, method string, entry *Anime) (*http.Response, error) {
buf := &bytes.Buffer{}

template.Must(
template.New("animeXML").
Parse(AnimeXMLTemplate)).
Execute(buf, entry)

payload := url.Values{}
payload.Set("data", buf.String())

req, err := http.NewRequest(
method,
address,
strings.NewReader(payload.Encode()),
)
if err != nil {
return nil, fmt.Errorf("error creating http request: %v", err)
}

req.Header.Set("Authorization", c.credentials)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error getting response for %d - %s update: %v",
entry.ID, entry.Title, err)
}
return resp, nil
}

//This works by scrapping the normal MAL website for given entry. It means that this method
//will stop working when they change something
func (c *Client) FetchDetails(entry *Anime) (*AnimeDetails, error) {
Expand Down

0 comments on commit 4b076c0

Please sign in to comment.