79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"archive/zip"
|
||
|
|
"bytes"
|
||
|
|
"encoding/xml"
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"github.com/ledongthuc/pdf"
|
||
|
|
)
|
||
|
|
|
||
|
|
func extractCVText(filename string, content []byte) (text string, err error) {
|
||
|
|
if len(content) == 0 {
|
||
|
|
return "", nil
|
||
|
|
}
|
||
|
|
switch strings.ToLower(filepath.Ext(filename)) {
|
||
|
|
case ".pdf":
|
||
|
|
defer func() {
|
||
|
|
if recovered := recover(); recovered != nil {
|
||
|
|
text = ""
|
||
|
|
err = fmt.Errorf("unreadable PDF")
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
reader, err := pdf.NewReader(bytes.NewReader(content), int64(len(content)))
|
||
|
|
if err != nil {
|
||
|
|
return "", fmt.Errorf("read PDF: %w", err)
|
||
|
|
}
|
||
|
|
plainText, err := reader.GetPlainText()
|
||
|
|
if err != nil {
|
||
|
|
return "", fmt.Errorf("extract PDF text: %w", err)
|
||
|
|
}
|
||
|
|
value, err := io.ReadAll(plainText)
|
||
|
|
if err != nil {
|
||
|
|
return "", fmt.Errorf("read PDF text: %w", err)
|
||
|
|
}
|
||
|
|
return string(value), nil
|
||
|
|
case ".docx":
|
||
|
|
return extractDOCX(content)
|
||
|
|
default:
|
||
|
|
return string(content), nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func extractDOCX(content []byte) (string, error) {
|
||
|
|
archive, err := zip.NewReader(bytes.NewReader(content), int64(len(content)))
|
||
|
|
if err != nil {
|
||
|
|
return "", fmt.Errorf("open DOCX: %w", err)
|
||
|
|
}
|
||
|
|
for _, file := range archive.File {
|
||
|
|
if file.Name != "word/document.xml" {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
stream, err := file.Open()
|
||
|
|
if err != nil {
|
||
|
|
return "", fmt.Errorf("open DOCX document: %w", err)
|
||
|
|
}
|
||
|
|
defer stream.Close()
|
||
|
|
decoder := xml.NewDecoder(stream)
|
||
|
|
var text strings.Builder
|
||
|
|
for {
|
||
|
|
token, err := decoder.Token()
|
||
|
|
if err == io.EOF {
|
||
|
|
return text.String(), nil
|
||
|
|
}
|
||
|
|
if err != nil {
|
||
|
|
return "", fmt.Errorf("parse DOCX document: %w", err)
|
||
|
|
}
|
||
|
|
if chars, ok := token.(xml.CharData); ok {
|
||
|
|
text.Write(chars)
|
||
|
|
text.WriteByte(' ')
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return "", fmt.Errorf("DOCX document body is missing")
|
||
|
|
}
|