Add geogebra previews

Co-authored-by: Florian Schade <fschade@owncloud.com>

Signed-off-by: Christian Richter <crichter@owncloud.com>
This commit is contained in:
Christian Richter
2023-11-24 15:10:51 +01:00
parent 1713041e14
commit c9f6b961f9
4 changed files with 93 additions and 12 deletions

View File

@@ -1,8 +1,10 @@
package preprocessor
import (
"archive/zip"
"bufio"
"bytes"
"fmt"
"image"
"image/draw"
"image/gif"
@@ -44,6 +46,36 @@ func (i GifDecoder) Convert(r io.Reader) (interface{}, error) {
return img, nil
}
type GgsDecoder struct{}
func (g GgsDecoder) Convert(r io.Reader) (interface{}, error) {
geogebraThumbnail := "_slide0/geogebra_thumbnail.png"
var buf bytes.Buffer
_, err := io.Copy(&buf, r)
if err != nil {
return nil, err
}
zipReader, err := zip.NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
if err != nil {
return nil, err
}
for _, file := range zipReader.File {
if file.Name == geogebraThumbnail {
thumbnail, err := file.Open()
if err != nil {
return nil, err
}
img, err := imaging.Decode(thumbnail, imaging.AutoOrientation(true))
if err != nil {
return nil, errors.Wrap(err, `could not decode the image`)
}
return img, nil
}
}
return nil, errors.New(fmt.Sprintf("%s not found", geogebraThumbnail))
}
type AudioDecoder struct{}
func (i AudioDecoder) Convert(r io.Reader) (interface{}, error) {
@@ -223,6 +255,8 @@ func ForType(mimeType string, opts map[string]interface{}) FileConverter {
return TxtToImageConverter{
fontLoader: fontLoader,
}
case "application/vnd.geogebra.slides":
return GgsDecoder{}
case "image/gif":
return GifDecoder{}
case "audio/flac":

View File

@@ -0,0 +1,57 @@
package preprocessor
import (
"bytes"
"image"
"io"
"reflect"
"testing"
)
// implement tests for the following structs and functions:
// ImageDecoder
// GifDecoder
// GgsDecoder
// TestImageDecoderConvert tests the function Convert of the struct ImageDecoder
func TestImageDecoderConvert(t *testing.T) {
type args struct {
r io.Reader
}
tests := []struct {
name string
i ImageDecoder
args args
want interface{}
wantErr bool
}{
{
name: "Test successful convert image",
args: args{
r: bytes.NewReader([]byte("")),
},
want: image.Image{},
wantErr: false,
},
{
name: "Test unsuccessful convert image",
args: args{
r: bytes.NewReader([]byte("")),
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
i := ImageDecoder{}
got, err := i.Convert(tt.args.r)
if (err != nil) != tt.wantErr {
t.Errorf("%q. ImageDecoder.Convert() error = %v, wantErr %v", tt.name, err, tt.wantErr)
return
}
if !reflect.DeepEqual(reflect.TypeOf(got), reflect.TypeOf(tt.want)) {
t.Errorf("%q. ImageDecoder.Convert() = %v, want %v", tt.name, got, tt.want)
}
}
}

View File

@@ -103,7 +103,7 @@ func (e GifEncoder) MimeType() string {
// or nil if the type is not supported.
func EncoderForType(fileType string) (Encoder, error) {
switch strings.ToLower(fileType) {
case typePng:
case typePng, typeGgs:
return PngEncoder{}, nil
case typeJpg, typeJpeg:
return JpegEncoder{}, nil

View File

@@ -71,24 +71,14 @@ func (g GifGenerator) imageToPaletted(img image.Image, p color.Palette) *image.P
return pm
}
// GgsGenerator is used to create a web friendly version of the provided ggs image.
type GgsGenerator struct{}
func (g GgsGenerator) Generate(size image.Rectangle, img interface{}, processor Processor) (interface{}, error) {
// TODO: write zip extractor, get image from zip, process image, return image
return nil, nil
}
// GeneratorForType returns the generator for a given file type
// or nil if the type is not supported.
func GeneratorForType(fileType string) (Generator, error) {
switch strings.ToLower(fileType) {
case typePng, typeJpg, typeJpeg:
case typePng, typeJpg, typeJpeg, typeGgs:
return SimpleGenerator{}, nil
case typeGif:
return GifGenerator{}, nil
case typeGgs:
return GgsGenerator{}, nil
default:
return nil, ErrNoEncoderForType
}