<commit_before>// Copyright 2015, <NAME>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package store

import (
	"bytes"
	"fmt"
	"net/http"

	"github.com/dhowden/tag"
)

// ArtworkFileSystem wraps another FileSystem, reworking file system operations
// to refer to artwork from the underlying file.
type ArtworkFileSystem struct {
	http.FileSystem
}

// Open the given file and return an http.File which contains the artwork, and hence
// the Name() of the returned file will have an extention for the artwork, not the
// media file.
func (afs ArtworkFileSystem) Open(path string) (http.File, error) {
	f, err := afs.FileSystem.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	stat, err := f.Stat()
	if err != nil {
		return nil, err
	}

	var m tag.Metadata
	m, err = tag.ReadFrom(f)
	if err != nil {
		return nil, fmt.Errorf("error extracting picture from '%v': %v", path, err)
	}

	p := m.Picture()
	if p == nil {
		return nil, fmt.Errorf("no picture attached to '%v'", path)
	}

	name := stat.Name()
	if p.Ext != "" {
		name += "." + p.Ext
	}

	return &file{
		ReadSeeker: bytes.NewReader(p.Data),
		stat: &fileInfo{
			name:    name,
			size:    int64(len(p.Data)),
			modTime: stat.ModTime(),
		},
	}, nil
}<commit_msg>Implement FaviconFileSystem.<commit_after>// Copyright 2015, <NAME>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package store

import (
	"bytes"
	"fmt"
	"image"
	"image/jpeg"
	"image/png"
	"net/http"
	"path/filepath"
	"strings"

	ico "github.com/Kodeworks/golang-image-ico"
	"github.com/dhowden/tag"
	"github.com/nfnt/resize"
)

// ArtworkFileSystem wraps another FileSystem, reworking file system operations
// to refer to artwork from the underlying file.
type ArtworkFileSystem struct {
	http.FileSystem
}

// Open the given file and return an http.File which contains the artwork, and hence
// the Name() of the returned file will have an extention for the artwork, not the
// media file.
func (afs ArtworkFileSystem) Open(path string) (http.File, error) {
	f, err := afs.FileSystem.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	stat, err := f.Stat()
	if err != nil {
		return nil, err
	}

	var m tag.Metadata
	m, err = tag.ReadFrom(f)
	if err != nil {
		return nil, fmt.Errorf("error extracting picture from '%v': %v", path, err)
	}

	p := m.Picture()
	if p == nil {
		return nil, fmt.Errorf("no picture attached to '%v'", path)
	}

	name := stat.Name()
	if p.Ext != "" {
		name += "." + p.Ext
	}

	return &file{
		ReadSeeker: bytes.NewReader(p.Data),
		stat: &fileInfo{
			name:    name,
			size:    int64(len(p.Data)),
			modTime: stat.ModTime(),
		},
	}, nil
}

// FaviconFileSystem wraps another FileSystem assumed to contain only images.
type FaviconFileSystem struct {
	http.FileSystem
}

func (ffs FaviconFileSystem) Open(path string) (http.File, error) {
	f, err := ffs.FileSystem.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	stat, err := f.Stat()
	if err != nil {
		return nil, err
	}

	filename := stat.Name()
	ext := filepath.Ext(filename)
	var img image.Image
	switch ext {
	case ".jpeg", ".jpg":
		img, err = jpeg.Decode(f)
	case ".png":
		img, err = png.Decode(f)
	default:
		err = fmt.Errorf("unsupported favicon image source: %v", stat.Name())
	}

	if err != nil {
		return nil, err
	}

	img = resize.Thumbnail(48, 48, img, resize.NearestNeighbor)
	buf := &bytes.Buffer{}
	err = ico.Encode(buf, img)
	if err != nil {
		return nil, err
	}

	icoFilename := strings.TrimSuffix(filename, ext) + ".ico"

	return &file{
		ReadSeeker: bytes.NewReader(buf.Bytes()),
		stat: &fileInfo{
			name:    icoFilename,
			size:    int64(buf.Len()),
			modTime: stat.ModTime(),
		},
	}, nil
}
{'fraction_non_alphanumeric': 0.1409784324039979, 'fraction_numerical': 0.004734350341925302, 'mean_word_length': 3.3265073947667805, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4286448', 'n_tokens_mistral': 1443, 'n_tokens_neox': 1348, 'n_words': 434}