<commit_before>// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build bimg
// +build bimg

package thumbnailer

import (
	"context"
	"os"
	"time"

	"github.com/matrix-org/dendrite/mediaapi/storage"
	"github.com/matrix-org/dendrite/mediaapi/types"
	"github.com/matrix-org/dendrite/setup/config"
	log "github.com/sirupsen/logrus"
	"gopkg.in/h2non/bimg.v1"
)

// GenerateThumbnails generates the configured thumbnail sizes for the source file
func GenerateThumbnails(
	ctx context.Context,
	src types.Path,
	configs []config.ThumbnailSize,
	mediaMetadata *types.MediaMetadata,
	activeThumbnailGeneration *types.ActiveThumbnailGeneration,
	maxThumbnailGenerators int,
	db *storage.Database,
	logger *log.Entry,
) (busy bool, errorReturn error) {
	buffer, err := bimg.Read(string(src))
	if err != nil {
		logger.WithError(err).WithField("src", src).Error("Failed to read src file")
		return false, err
	}
	img := bimg.NewImage(buffer)
	for _, config := range configs {
		// Note: createThumbnail does locking based on activeThumbnailGeneration
		busy, err = createThumbnail(
			ctx, src, img, config, mediaMetadata, activeThumbnailGeneration,
			maxThumbnailGenerators, db, logger,
		)
		if err != nil {
			logger.WithError(err).WithField("src", src).Error("Failed to generate thumbnails")
			return false, err
		}
		if busy {
			return true, nil
		}
	}
	return false, nil
}

// GenerateThumbnail generates the configured thumbnail size for the source file
func GenerateThumbnail(
	ctx context.Context,
	src types.Path,
	config types.ThumbnailSize,
	mediaMetadata *types.MediaMetadata,
	activeThumbnailGeneration *types.ActiveThumbnailGeneration,
	maxThumbnailGenerators int,
	db *storage.Database,
	logger *log.Entry,
) (busy bool, errorReturn error) {
	buffer, err := bimg.Read(string(src))
	if err != nil {
		logger.WithError(err).WithFields(log.Fields{
			"src": src,
		}).Error("Failed to read src file")
		return false, err
	}
	img := bimg.NewImage(buffer)
	// Note: createThumbnail does locking based on activeThumbnailGeneration
	busy, err = createThumbnail(
		ctx, src, img, config, mediaMetadata, activeThumbnailGeneration,
		maxThumbnailGenerators, db, logger,
	)
	if err != nil {
		logger.WithError(err).WithFields(log.Fields{
			"src": src,
		}).Error("Failed to generate thumbnails")
		return false, err
	}
	if busy {
		return true, nil
	}
	return false, nil
}

// createThumbnail checks if the thumbnail exists, and if not, generates it
// Thumbnail generation is only done once for each non-existing thumbnail.
func createThumbnail(
	ctx context.Context,
	src types.Path,
	img *bimg.Image,
	config types.ThumbnailSize,
	mediaMetadata *types.MediaMetadata,
	activeThumbnailGeneration *types.ActiveThumbnailGeneration,
	maxThumbnailGenerators int,
	db *storage.Database,
	logger *log.Entry,<commit_msg>🏗️ mediaapi/thumbnailer: fix build with bimg (#2440)<commit_after>// Copyright 2017 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build bimg
// +build bimg

package thumbnailer

import (
	"context"
	"os"
	"time"

	"github.com/matrix-org/dendrite/mediaapi/storage"
	"github.com/matrix-org/dendrite/mediaapi/types"
	"github.com/matrix-org/dendrite/setup/config"
	log "github.com/sirupsen/logrus"
	"gopkg.in/h2non/bimg.v1"
)

// GenerateThumbnails generates the configured thumbnail sizes for the source file
func GenerateThumbnails(
	ctx context.Context,
	src types.Path,
	configs []config.ThumbnailSize,
	mediaMetadata *types.MediaMetadata,
	activeThumbnailGeneration *types.ActiveThumbnailGeneration,
	maxThumbnailGenerators int,
	db storage.Database,
	logger *log.Entry,
) (busy bool, errorReturn error) {
	buffer, err := bimg.Read(string(src))
	if err != nil {
		logger.WithError(err).WithField("src", src).Error("Failed to read src file")
		return false, err
	}
	img := bimg.NewImage(buffer)
	for _, config := range configs {
		// Note: createThumbnail does locking based on activeThumbnailGeneration
		busy, err = createThumbnail(
			ctx, src, img, types.ThumbnailSize(config), mediaMetadata, activeThumbnailGeneration,
			maxThumbnailGenerators, db, logger,
		)
		if err != nil {
			logger.WithError(err).WithField("src", src).Error("Failed to generate thumbnails")
			return false, err
		}
		if busy {
			return true, nil
		}
	}
	return false, nil
}

// GenerateThumbnail generates the configured thumbnail size for the source file
func GenerateThumbnail(
	ctx context.Context,
	src types.Path,
	config types.ThumbnailSize,
	mediaMetadata *types.MediaMetadata,
	activeThumbnailGeneration *types.ActiveThumbnailGeneration,
	maxThumbnailGenerators int,
	db storage.Database,
	logger *log.Entry,
) (busy bool, errorReturn error) {
	buffer, err := bimg.Read(string(src))
	if err != nil {
		logger.WithError(err).WithFields(log.Fields{
			"src": src,
		}).Error("Failed to read src file")
		return false, err
	}
	img := bimg.NewImage(buffer)
	// Note: createThumbnail does locking based on activeThumbnailGeneration
	busy, err = createThumbnail(
		ctx, src, img, config, mediaMetadata, activeThumbnailGeneration,
		maxThumbnailGenerators, db, logger,
	)
	if err != nil {
		logger.WithError(err).WithFields(log.Fields{
			"src": src,
		}).Error("Failed to generate thumbnails")
		return false, err
	}
	if busy {
		return true, nil
	}
	return false, nil
}

// createThumbnail checks if the thumbnail exists, and if not, generates it
// Thumbnail generation is only done once for each non-existing thumbnail.
func createThumbnail(
	ctx context.Context,
	src types.Path,
	img *bimg.Image,
	config types.ThumbnailSize,
	mediaMetadata *types.MediaMetadata,
	activeThumbnailGeneration *types.ActiveThumbnailGeneration,
	maxThumbnailGenerators int,
	db storage.Database,
	logger *log.Entry,
{'fraction_non_alphanumeric': 0.10299101222926182, 'fraction_numerical': 0.0035361720937085606, 'mean_word_length': 4.452208835341366, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '238162', 'n_tokens_mistral': 2232, 'n_tokens_neox': 2148, 'n_words': 651}