Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
iArmanKarimi committed Dec 3, 2022
1 parent d4fb74f commit f19903d
Show file tree
Hide file tree
Showing 7 changed files with 430 additions and 38 deletions.
30 changes: 15 additions & 15 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
52 changes: 52 additions & 0 deletions Cataas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package CataasAPI

import "net/url"

type Size string
type Filter string

// small or sm, medium or md, square or sq, original or or
const (
SIZE_SMALL Size = "sm"
SIZE_MEDIUM Size = "md"
SIZE_SQUARE Size = "sq"
SIZE_ORIGINAL Size = "or"
)

// blur, mono, sepia, negative, paint, pixel
const (
FILTER_BLUR Filter = "blur"
FILTER_MONO Filter = "mono"
FILTER_PAINT Filter = "paint"
FILTER_PIXEL Filter = "pixel"
FILTER_SEPIA Filter = "sepia"
FILTER_NEGATIVE Filter = "negative"
)

var uri = &url.URL{
Host: "cataas.com",
Scheme: "https",
}

type Cataas struct {
Gif bool
Tag string
Text string
Width uint
Height uint
TextSize uint
TextColor string
Size Size
Filter Filter
}

type CatByTag struct {
Id string `json:"id"`
CreatedAt string `json:"created_at"`
Tags []string `json:"tags"`
}

type GetCatsOptions struct {
Skip uint
Limit uint
}
42 changes: 21 additions & 21 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
MIT License

Copyright (c) 2022 Arman karimi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
MIT License
Copyright (c) 2022 Arman karimi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
131 changes: 131 additions & 0 deletions Methods.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package CataasAPI

import (
"encoding/json"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"path"
"strconv"
"strings"
)

const (
pathCat = "cat"
pathTags = "api/cats"
pathAllTags = "api/tags"
)

/* Returns url to be used */
func (c *Cataas) Encode() *url.URL {
uri.Path = pathCat
q := uri.Query()
if c.Gif {
c.Tag = "gif"
}
if c.Tag != "" {
uri.Path = path.Join(uri.Path, c.Tag)
}
if c.Text != "" {
uri.Path = path.Join(uri.Path, "says/"+c.Text)
q.Set("size", strconv.Itoa(int(c.TextSize)))
if c.TextColor != "" {
q.Set("color", c.TextColor)
}
}
if c.Size != "" {
q.Set("type", string(c.Size))
}
if c.Filter != "" {
q.Set("filter", string(c.Filter))
}
q.Set("width", strconv.Itoa(int(c.Width)))
q.Set("height", strconv.Itoa(int(c.Height)))
uri.RawQuery = q.Encode()
return uri
}

/* sends get request then reads the response body and returns the data.
can be used after encoding using Encode or EncodeById.
*/
func (c *Cataas) Get() (img_data []byte, err error) {
var resp *http.Response
resp, err = http.Get(uri.String())
if err != nil {
return nil, err
}
defer resp.Body.Close()
img_data, err = ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return img_data, nil
}

/* Download image and save it to the given path */
func (c *Cataas) Download(path string) (err error) {
// Todo: add file_name arg and join it with path
var resp *http.Response
resp, err = http.Get(uri.String())
if err != nil {
return err
}
defer resp.Body.Close()
var out *os.File
out, err = os.Create(path)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return err
}

/* returns the encoded url by using the id of the image */
func (c *Cataas) EncodeById(id string) *url.URL {
uri.Path = pathCat + "/" + id
return uri
}

/* get all tags */
func (c *Cataas) GetAllTags() (tags []string, err error) {
uri.Path = pathAllTags
var data []byte
data, err = c.Get()
if err != nil {
return nil, err
}
err = json.Unmarshal(data, &tags)
return tags, err
}

/* get cats which include the given tag(s) */
func (c *Cataas) GetCats(tags []string, options *GetCatsOptions) (cats []*CatByTag, err error) {
var (
skip = "0"
limit = "0"
)
if options != nil {
skip = strconv.Itoa(int(options.Skip))
limit = strconv.Itoa(int(options.Limit))
}
q := uri.Query()
q.Set("tags", strings.Join(tags, ","))
q.Set("skip", skip)
q.Set("limit", limit)
uri.Path = pathTags
uri.RawQuery = q.Encode()
var data []byte
data, err = c.Get()
if err != nil {
return nil, err
}
container := make([]*CatByTag, 0, 200)
err = json.Unmarshal(data, &container)
if err != nil {
return nil, err
}
return container, nil
}
133 changes: 133 additions & 0 deletions Methods_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package CataasAPI

import (
"errors"
"math/rand"
"os"
"path"
"strconv"
"strings"
"testing"
"time"
)

func print_test(t *testing.T, want interface{}, got interface{}) {
t.Errorf(`want: %v ; got: %v`, want, got)
}

func TestEncode(t *testing.T) {
// want := "https://"
// got := c.Encode().String()
const (
gif = false
tag = "cute,fluffy"
text = "hello"
width = 200
height = 200
textSize = 20
textColor = "Blue"
size = SIZE_SMALL
filter = FILTER_BLUR
)
c := &Cataas{
Gif: gif,
Tag: tag,
Text: text,
Width: width,
Height: height,
TextSize: textSize,
TextColor: textColor,
Size: SIZE_SMALL,
Filter: FILTER_BLUR,
}
uri := c.Encode()

if _text := path.Base(uri.Path); _text != text {
print_test(t, text, _text)
}
if _tag := strings.Split(path.Dir(uri.Path), "/")[1]; _tag != tag {
print_test(t, tag, _tag)
}
if _width := uri.Query().Get("width"); _width != strconv.Itoa(width) {
print_test(t, width, _width)
}
if _height := uri.Query().Get("height"); _height != strconv.Itoa(height) {
print_test(t, height, _height)
}
if _text_size := uri.Query().Get("size"); _text_size != strconv.Itoa(textSize) {
print_test(t, textSize, _text_size)
}
if _text_color := uri.Query().Get("color"); _text_color != textColor {
print_test(t, textColor, _text_color)
}
if _size := uri.Query().Get("type"); _size != string(size) {
print_test(t, string(size), _size)
}
if _filter := uri.Query().Get("filter"); _filter != string(filter) {
print_test(t, string(filter), _filter)
}
if _gif := uri.Query().Get("gif"); _gif != "" {
t.Error("Gif option not be set when tag is")
}
}

func TestGet(t *testing.T) {
c := &Cataas{Text: "Hello", TextSize: 20}
img, err := c.Get()
if err != nil {
t.Error(err)
}
if len(img) < 1 {
t.Error("Empty image")
}
}

func TestDownload(t *testing.T) {
c := &Cataas{}
const file_path = "__img__test__.png"
err := c.Download(file_path)
if err != nil {
t.Error(err)
}
if _, err := os.Stat(file_path); err == nil {
os.Remove(file_path)
} else if errors.Is(err, os.ErrNotExist) {
t.Error("File was not created. download failed.")
} else {
t.Error(err)
}
}

func TestEncodeById(t *testing.T) {
c := &Cataas{}
id := rand.New(rand.NewSource(time.Now().Unix())).Int()
uri := c.EncodeById(strconv.Itoa(id))
if _id, err := strconv.Atoi(path.Base(uri.Path)); err != nil {
t.Error(err)
} else if _id != id {
print(t, id, _id)
}
}

func TestGetAllTags(t *testing.T) {
c := &Cataas{}
if tags, err := c.GetAllTags(); err != nil {
t.Error(err)
} else if len(tags) < 1 {
t.Error("Empty tags list")
}
}

// Todo
// func TestGetCats(t *testing.T) { }

// Benchmarks //
func BenchmarkTestGet_5(b *testing.B) {
c := &Cataas{}
for i := 0; i < 5; i++ {
_, err := c.Get()
if err != nil {
_ = err.Error()
}
}
}
Loading

0 comments on commit f19903d

Please sign in to comment.