752fb2e2c0
Text Extraction Clean Up + Parallelization * merged_Call * directchildren * bitofimprovements * go * parallel * fixfullsuite * pondforconcurrency * comments * muchdone * bitsofclean * stabilisedtests * snappy * threadpooltests * childelements * testspassed
130 lines
3.0 KiB
Go
130 lines
3.0 KiB
Go
package documenttext
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"log/slog"
|
|
"strings"
|
|
|
|
documenttypes "queryorchestration/internal/document/types"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/service/textract"
|
|
"github.com/aws/aws-sdk-go-v2/service/textract/types"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type cell struct {
|
|
value string
|
|
row int
|
|
column int
|
|
}
|
|
|
|
func (s *Service) addTable(ctx context.Context, block types.Block, blockMap map[uuid.UUID]types.Block, builder *strings.Builder) error {
|
|
params := tableParams{
|
|
maxRow: 0,
|
|
maxColumn: 0,
|
|
table: []cell{},
|
|
}
|
|
|
|
directChildren := s.getDirectChildren(block, blockMap)
|
|
|
|
for _, uid := range directChildren {
|
|
s.addComponentTable(ctx, blockMap[uid], blockMap, ¶ms)
|
|
}
|
|
|
|
tableArr := make([][]string, params.maxRow)
|
|
for i := range tableArr {
|
|
tableArr[i] = make([]string, params.maxColumn)
|
|
}
|
|
|
|
for _, cell := range params.table {
|
|
tableArr[cell.row][cell.column] = cell.value
|
|
}
|
|
|
|
jsonData, err := json.Marshal(tableArr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
builder.WriteString("-------Table Start--------\n")
|
|
builder.WriteString(string(jsonData))
|
|
builder.WriteString("\n-------Table End--------\n")
|
|
|
|
return nil
|
|
}
|
|
|
|
type tableParams struct {
|
|
maxRow int
|
|
maxColumn int
|
|
table []cell
|
|
}
|
|
|
|
func (s *Service) addComponentTable(ctx context.Context, block types.Block, blockMap map[uuid.UUID]types.Block, params *tableParams) {
|
|
switch block.BlockType {
|
|
case types.BlockTypeMergedCell:
|
|
for _, id := range s.getChildIds(block) {
|
|
s.addComponentTable(ctx, blockMap[id], blockMap, params)
|
|
}
|
|
case types.BlockTypeCell:
|
|
var str strings.Builder
|
|
for _, uid := range s.getChildIds(block) {
|
|
if blockMap[uid].BlockType == types.BlockTypeWord {
|
|
if str.String() != "" {
|
|
str.WriteRune(' ')
|
|
}
|
|
str.WriteString(*blockMap[uid].Text)
|
|
}
|
|
|
|
if params.maxRow < int(*block.RowIndex) {
|
|
params.maxRow = int(*block.RowIndex)
|
|
}
|
|
if params.maxColumn < int(*block.ColumnIndex) {
|
|
params.maxColumn = int(*block.ColumnIndex)
|
|
}
|
|
|
|
params.table = append(params.table, cell{
|
|
column: int(*block.ColumnIndex) - 1,
|
|
row: int(*block.RowIndex) - 1,
|
|
value: str.String(),
|
|
})
|
|
}
|
|
default:
|
|
slog.Info("unhandled block type in table", "type", block.BlockType)
|
|
}
|
|
}
|
|
|
|
func (s *Service) getTables(ctx context.Context, document documenttypes.File, index int) ([]uuid.UUID, map[uuid.UUID]types.Block, error) {
|
|
pageBytes, err := document.GetPageAsPNG(ctx, index)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
res, err := s.cfg.GetTextractClient().AnalyzeDocument(ctx, &textract.AnalyzeDocumentInput{
|
|
Document: &types.Document{
|
|
Bytes: pageBytes,
|
|
},
|
|
FeatureTypes: []types.FeatureType{
|
|
types.FeatureTypeTables,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
tables := []uuid.UUID{}
|
|
for _, block := range res.Blocks {
|
|
if block.BlockType == types.BlockTypeTable {
|
|
id, err := uuid.Parse(*block.Id)
|
|
if err != nil {
|
|
slog.Warn("error parsing block id", "error", err, "id", *block.Id)
|
|
continue
|
|
}
|
|
|
|
tables = append(tables, id)
|
|
}
|
|
}
|
|
blocks := s.getBlockMap(res.Blocks)
|
|
|
|
return tables, blocks, nil
|
|
}
|