Replace all infra services with interfaces
This commit is contained in:
20
internal/adapter/yandex/memory.go
Normal file
20
internal/adapter/yandex/memory.go
Normal 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
|
||||
}
|
95
internal/adapter/yandex/recognizer.go
Normal file
95
internal/adapter/yandex/recognizer.go
Normal 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
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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)
|
Reference in New Issue
Block a user