Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kadai1 nagaa052 #10

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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 kadai1/nagaa052/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
21 changes: 21 additions & 0 deletions kadai1/nagaa052/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
NAME := gocon

GO ?= go
BUILD_DIR=./build
BINARY ?= $(BUILD_DIR)/$(NAME)

.PHONY: all
all: clean test build

.PHONY: test
test:
$(GO) test -v ./...

.PHONY: clean
clean:
$(GO) clean
rm -f $(BINARY)

.PHONY: build
build:
$(GO) build -o $(BINARY) -v
20 changes: 20 additions & 0 deletions kadai1/nagaa052/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
gocon
===
image convert command by golang

### Usage

```
Usage:
gocon [option] <directory path>
Options:
-d string
Convert output directory. (default "out")
-f string
Convert image format. The input format is [In]:[Out]. image is jpeg|png. (default "jpeg:png")
```

#### Example
```
$ gocon -f jpeg:png -d output image/jpegs
```
1 change: 1 addition & 0 deletions kadai1/nagaa052/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module github.com/gopherdojo/dojo5/kadai1/nagaa052
34 changes: 34 additions & 0 deletions kadai1/nagaa052/internal/gocon/format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package gocon

import "fmt"

// ImgFormat is a convertible image format.
type ImgFormat string

const (
JPEG ImgFormat = "jpeg"
PNG ImgFormat = "png"
)

// String is converted to string type and returned.
func (i *ImgFormat) String() string {
return string(*i)
}

// GetExtentions returns the extension of the target format.
func (i *ImgFormat) GetExtentions() ([]string, error) {
if !i.Exist() {
return nil, fmt.Errorf("Format that does not exist is an error")
}

if *i == JPEG {
return []string{".jpeg", ".jpg"}, nil
}

return []string{"." + string(*i)}, nil
}

// Exist examines available formats.
func (i *ImgFormat) Exist() bool {
return *i == JPEG || *i == PNG
}
60 changes: 60 additions & 0 deletions kadai1/nagaa052/internal/gocon/format_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package gocon_test

import (
"fmt"
"testing"

"github.com/gopherdojo/dojo5/kadai1/nagaa052/internal/gocon"
)

func TestGetExtentions(t *testing.T) {
errMessage := `
Incorrect extension.
expected: %s
actual: %s
`

cases := []struct {
name string
format string
expected []string
isError bool
}{
{
name: "success test",
format: "jpeg",
expected: []string{".jpeg", ".jpg"},
isError: false,
},
{
name: "format does not exist",
format: "hogehoge",
expected: []string{".hogehoge"},
isError: true,
},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
i := gocon.ImgFormat(c.format)
actual, err := i.GetExtentions()
if c.isError {
if err == nil {
t.Error(err)
}
} else {
if err != nil {
t.Error(err)
}

if len(actual) <= 0 {
t.Error(fmt.Sprintf(errMessage, c.expected, actual))
}

if c.expected[0] != actual[0] {
t.Error(fmt.Sprintf(errMessage, c.expected, actual))
}
}
})
}
}
145 changes: 145 additions & 0 deletions kadai1/nagaa052/internal/gocon/gocon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
Provides the ability to perform image conversion with gocon.
*/
package gocon

import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"sync"

"github.com/gopherdojo/dojo5/kadai1/nagaa052/pkg/convert"
"github.com/gopherdojo/dojo5/kadai1/nagaa052/pkg/search"
)

const (
ExitOK = iota
ExitError
)

const (
SuccessConvertFileMessageFmt string = "convert file : %s\n"
)

type gocon struct {
SrcDir string
Options
outStream, errStream io.Writer
}

// Options is a specifiable option. Default is DefaultOptions.
type Options struct {
FromFormat ImgFormat
ToFormat ImgFormat
DestDir string
}

// DefaultOptions is the default value of Options.
var DefaultOptions = Options{
FromFormat: JPEG,
ToFormat: PNG,
DestDir: "out",
}

// New is Generate a new gocon.
func New(srcDir string, opt Options, outStream, errStream io.Writer) (*gocon, error) {
if srcDir == "" {
return nil, fmt.Errorf("target path is required")
}

srcDir, err := filepath.Abs(srcDir)
if err != nil {
return nil, fmt.Errorf("Invalid directory specification")
}

if _, err := os.Stat(srcDir); err != nil {
return nil, err
}

if opt.FromFormat == "" {
opt.FromFormat = DefaultOptions.FromFormat
}

if opt.ToFormat == "" {
opt.ToFormat = DefaultOptions.ToFormat
}

if opt.DestDir == "" {
opt.DestDir = DefaultOptions.DestDir
}

opt.DestDir, err = filepath.Abs(opt.DestDir)
if err != nil {
return nil, fmt.Errorf("Invalid directory specification")
}

return &gocon{
SrcDir: srcDir,
Options: opt,
outStream: outStream,
errStream: errStream,
}, nil
}

// Run is executes gocon.
func (gc *gocon) Run() int {

wg := &sync.WaitGroup{}
chw := make(chan string)
defer close(chw)

ext, err := gc.FromFormat.GetExtentions()
if err != nil {
fmt.Fprintf(gc.errStream, "%+v\n", err)
return ExitError
}

err = search.WalkWithExtHandle(gc.SrcDir, ext,
func(srcImgPath string, info os.FileInfo, err error) {
if err != nil {
fmt.Fprintf(gc.errStream, "%+v\n", err)
return
}

wg.Add(1)
go func() {
defer wg.Done()
destFilePath, err := gc.convert(srcImgPath, info)
if err != nil {
fmt.Fprintf(gc.errStream, "%+v\n", err)
return
}

fmt.Fprintf(gc.outStream, SuccessConvertFileMessageFmt, destFilePath)
}()
})
if err != nil {
fmt.Fprintf(gc.errStream, "%+v\n", err)
return ExitError
}

wg.Wait()
return ExitOK
}

func (gc *gocon) convert(srcImgPath string, info os.FileInfo) (string, error) {
srcImgDir := strings.Replace(srcImgPath, "/"+info.Name(), "", -1)
destDir := strings.Replace(srcImgDir, gc.SrcDir, gc.DestDir, -1)

con, err := convert.New(srcImgPath, destDir)
if err != nil {
return "", err
}

switch gc.ToFormat {
case JPEG:
return con.ToJpeg(&convert.JpegOptions{})
case PNG:
return con.ToPng()
default:
return "", fmt.Errorf("There is no convertible format")
}
}
82 changes: 82 additions & 0 deletions kadai1/nagaa052/internal/gocon/gocon_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package gocon_test

import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"
"testing"

"github.com/gopherdojo/dojo5/kadai1/nagaa052/internal/gocon"
)

func TestRun(t *testing.T) {
errMessage := `
It was not converted properly.
Error: %v
`
streamErrMessage := `
Convert Error.
%v
`

srcDir, err := filepath.Abs(filepath.Join("testdata", t.Name()))
if err != nil {
t.Error(err)
}
destDir, err := filepath.Abs("out")
if err != nil {
t.Error(err)
}

cases := []struct {
name string
options gocon.Options
expected int
isError bool
}{
{
name: "Success Test",
options: gocon.Options{
FromFormat: gocon.JPEG,
ToFormat: gocon.PNG,
DestDir: destDir,
},
expected: gocon.ExitOK,
isError: false,
},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
g, err := gocon.New(srcDir, c.options, outStream, errStream)
if !c.isError && err != nil {
t.Error(fmt.Sprintf("gocon make error : %+v", err))
}

actual := g.Run()

if _, err := os.Stat(destDir); err == nil {
if err := os.RemoveAll(destDir); err != nil {
fmt.Println(err)
}
}

if c.expected != actual {
t.Error(fmt.Sprintf(errMessage, c.expected, actual))
}

if errStream.String() != "" {
t.Error(fmt.Sprintf(streamErrMessage, errStream.String()))
}

messageFmt := strings.Replace(gocon.SuccessConvertFileMessageFmt, "\n", "", -1)
expectedMessage := fmt.Sprintf(messageFmt, destDir)
if !strings.Contains(outStream.String(), expectedMessage) {
t.Error("Conversion failed")
}
})
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading