Replace all infra services with interfaces

This commit is contained in:
2025-08-13 09:20:45 +03:00
parent 3f31bd5ff2
commit f6b5e835a4
9 changed files with 260 additions and 85 deletions

View File

@@ -0,0 +1,20 @@
package yandex
import (
"git.vakhrushev.me/av/transcriber/internal/entity"
"github.com/google/uuid"
)
type MemoryAudioRecognizer struct{}
func (r *MemoryAudioRecognizer) RecognizeFile(filePath string) (operationID string, err error) {
return uuid.NewString(), nil
}
func (r *MemoryAudioRecognizer) GetRecognitionText(operationID string) (string, error) {
return "Foo bar, Baz.", nil
}
func (r *MemoryAudioRecognizer) CheckRecognitionStatus(operationID string) (*entity.RecognitionResult, error) {
return entity.NewCompletedResult(), nil
}

View File

@@ -0,0 +1,95 @@
package yandex
import (
"fmt"
"path/filepath"
"git.vakhrushev.me/av/transcriber/internal/entity"
)
type YandexAudioRecognizerConfig struct {
// s3
Region string
AccessKey string
SecretKey string
BucketName string
Endpoint string
// speech kit
ApiKey string
FolderID string
}
type YandexAudioRecognizerService struct {
s3Sevice *yandexS3Service
sttService *speechKitService
}
func NewYandexAudioRecognizerService(cfg YandexAudioRecognizerConfig) (*YandexAudioRecognizerService, error) {
s3, err := newYandexS3Service(s3Config{
Region: cfg.Region,
AccessKey: cfg.AccessKey,
SecretKey: cfg.SecretKey,
BucketName: cfg.BucketName,
Endpoint: cfg.Endpoint,
})
if err != nil {
return nil, err
}
stt, err := newSpeechKitService(speechKitConfig{
ApiKey: cfg.ApiKey,
FolderID: cfg.FolderID,
})
if err != nil {
return nil, err
}
return &YandexAudioRecognizerService{
s3Sevice: s3,
sttService: stt,
}, nil
}
func (s *YandexAudioRecognizerService) Close() error {
return s.sttService.Close()
}
func (s *YandexAudioRecognizerService) RecognizeFile(filePath string) (string, error) {
fileName := filepath.Base(filePath)
err := s.s3Sevice.uploadFile(filePath, fileName)
if err != nil {
return "", err
}
uri := s.s3Sevice.fileUrl(fileName)
opId, err := s.sttService.recognizeFileFromS3(uri)
if err != nil {
return "", err
}
return opId, nil
}
func (s *YandexAudioRecognizerService) GetRecognitionText(operationID string) (string, error) {
return s.sttService.getRecognitionText(operationID)
}
func (s *YandexAudioRecognizerService) CheckRecognitionStatus(operationID string) (*entity.RecognitionResult, error) {
operation, err := s.sttService.checkOperationStatus(operationID)
if err != nil {
return nil, err
}
if !operation.Done {
return entity.NewInProgressResult(), nil
}
if opErr := operation.GetError(); opErr != nil {
errorText := fmt.Sprintf("operation failed: code %d, message: %s", opErr.Code, opErr.Message)
return entity.NewFailedResult(errorText), nil
}
return entity.NewCompletedResult(), nil
}

View File

@@ -1,4 +1,4 @@
package s3
package yandex
import (
"context"
@@ -13,7 +13,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/s3"
)
type S3Config struct {
type s3Config struct {
Region string
AccessKey string
SecretKey string
@@ -21,14 +21,14 @@ type S3Config struct {
Endpoint string
}
type YandexS3Service struct {
type yandexS3Service struct {
client *s3.Client
uploader *manager.Uploader
bucketName string
endpoint string
}
func NewYandexS3Service(cfg S3Config) (*YandexS3Service, error) {
func newYandexS3Service(cfg s3Config) (*yandexS3Service, error) {
if cfg.Region == "" || cfg.AccessKey == "" || cfg.SecretKey == "" || cfg.BucketName == "" {
return nil, fmt.Errorf("missing required S3 configuration parameters")
}
@@ -57,7 +57,7 @@ func NewYandexS3Service(cfg S3Config) (*YandexS3Service, error) {
uploader := manager.NewUploader(client)
return &YandexS3Service{
return &yandexS3Service{
client: client,
uploader: uploader,
bucketName: cfg.BucketName,
@@ -65,7 +65,7 @@ func NewYandexS3Service(cfg S3Config) (*YandexS3Service, error) {
}, nil
}
func (s *YandexS3Service) UploadFile(filePath, fileName string) error {
func (s *yandexS3Service) uploadFile(filePath, fileName string) error {
file, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("failed to open file %s: %w", filePath, err)
@@ -84,20 +84,7 @@ func (s *YandexS3Service) UploadFile(filePath, fileName string) error {
return nil
}
func (s *YandexS3Service) FileUrl(fileName string) string {
func (s *yandexS3Service) fileUrl(fileName string) string {
endpoint := strings.TrimRight(s.endpoint, "/")
return fmt.Sprintf("%s/%s/%s", endpoint, s.bucketName, fileName)
}
// test service
type TestS3service struct {
}
func (s *TestS3service) UploadFile(filePath, fileName string) error {
return nil
}
func (s *TestS3service) FileUrl(fileName string) string {
return fileName
}

View File

@@ -1,9 +1,8 @@
package speechkit
package yandex
import (
"context"
"fmt"
"os"
"strings"
"google.golang.org/grpc"
@@ -21,7 +20,12 @@ const (
RecognitionModel = "deferred-general"
)
type SpeechKitService struct {
type speechKitConfig struct {
ApiKey string
FolderID string
}
type speechKitService struct {
sttConn *grpc.ClientConn
opConn *grpc.ClientConn
sttClient stt.AsyncRecognizerClient
@@ -30,9 +34,9 @@ type SpeechKitService struct {
folderID string
}
func NewSpeechKitService() (*SpeechKitService, error) {
apiKey := os.Getenv("YANDEX_CLOUD_API_KEY")
folderID := os.Getenv("YANDEX_CLOUD_FOLDER_ID")
func newSpeechKitService(cfg speechKitConfig) (*speechKitService, error) {
apiKey := cfg.ApiKey
folderID := cfg.FolderID
if apiKey == "" || folderID == "" {
return nil, fmt.Errorf("missing required Yandex Cloud environment variables")
@@ -55,7 +59,7 @@ func NewSpeechKitService() (*SpeechKitService, error) {
sttClient := stt.NewAsyncRecognizerClient(sttConn)
opClient := operation.NewOperationServiceClient(opConn)
return &SpeechKitService{
return &speechKitService{
sttConn: sttConn,
opConn: opConn,
sttClient: sttClient,
@@ -65,7 +69,7 @@ func NewSpeechKitService() (*SpeechKitService, error) {
}, nil
}
func (s *SpeechKitService) Close() error {
func (s *speechKitService) Close() error {
var err1, err2 error
if s.sttConn != nil {
err1 = s.sttConn.Close()
@@ -79,8 +83,8 @@ func (s *SpeechKitService) Close() error {
return err2
}
// RecognizeFileFromS3 запускает асинхронное распознавание файла из S3
func (s *SpeechKitService) RecognizeFileFromS3(s3URI string) (string, error) {
// recognizeFileFromS3 запускает асинхронное распознавание файла из S3
func (s *speechKitService) recognizeFileFromS3(s3URI string) (string, error) {
ctx := context.Background()
// Добавляем авторизацию и folder_id в контекст
@@ -123,7 +127,7 @@ func (s *SpeechKitService) RecognizeFileFromS3(s3URI string) (string, error) {
}
// GetRecognitionResult получает результат распознавания по ID операции
func (s *SpeechKitService) GetRecognitionText(operationID string) (string, error) {
func (s *speechKitService) getRecognitionText(operationID string) (string, error) {
ctx := context.Background()
// Добавляем авторизацию и folder_id в контекст
@@ -162,8 +166,8 @@ func (s *SpeechKitService) GetRecognitionText(operationID string) (string, error
return sb.String(), nil
}
// CheckOperationStatus проверяет статус операции распознавания
func (s *SpeechKitService) CheckOperationStatus(operationID string) (*operation.Operation, error) {
// checkOperationStatus проверяет статус операции распознавания
func (s *speechKitService) checkOperationStatus(operationID string) (*operation.Operation, error) {
ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Api-Key "+s.apiKey)