start rmser

This commit is contained in:
2025-11-29 08:40:24 +03:00
commit 5aa2238eea
2117 changed files with 375169 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
package ocr_client
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/textproto"
"time"
)
type Client struct {
pythonServiceURL string
httpClient *http.Client
}
func NewClient(pythonServiceURL string) *Client {
return &Client{
pythonServiceURL: pythonServiceURL,
httpClient: &http.Client{
// OCR может быть долгим, ставим таймаут побольше (например, 30 сек)
Timeout: 30 * time.Second,
},
}
}
// ProcessImage отправляет изображение в Python и возвращает сырые данные
func (c *Client) ProcessImage(ctx context.Context, imageData []byte, filename string) (*RecognitionResult, error) {
// 1. Создаем буфер для multipart формы
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// Создаем заголовок части вручную, чтобы прописать Content-Type: image/jpeg
h := make(textproto.MIMEHeader)
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="image"; filename="%s"`, filename))
h.Set("Content-Type", "image/jpeg") // Явно указываем, что это картинка
part, err := writer.CreatePart(h)
if err != nil {
return nil, fmt.Errorf("create part error: %w", err)
}
// Записываем байты картинки
if _, err := io.Copy(part, bytes.NewReader(imageData)); err != nil {
return nil, fmt.Errorf("copy file error: %w", err)
}
// Закрываем writer, чтобы записать boundary
if err := writer.Close(); err != nil {
return nil, fmt.Errorf("writer close error: %w", err)
}
// 2. Создаем запрос
req, err := http.NewRequestWithContext(ctx, "POST", c.pythonServiceURL+"/recognize", body)
if err != nil {
return nil, fmt.Errorf("create request error: %w", err)
}
// Важно: Content-Type с boundary
req.Header.Set("Content-Type", writer.FormDataContentType())
// 3. Отправляем
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("ocr service request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
bodyBytes, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("ocr service error (code %d): %s", resp.StatusCode, string(bodyBytes))
}
// 4. Парсим ответ
var result RecognitionResult
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("json decode error: %w", err)
}
return &result, nil
}