Initial commit

This commit is contained in:
2023-03-26 16:11:00 +03:00
commit 92469fa3a2
47 changed files with 5610 additions and 0 deletions

30
entity/file.go Normal file
View File

@@ -0,0 +1,30 @@
package entity
import (
"time"
"github.com/gabriel-vasile/mimetype"
"github.com/google/uuid"
)
func NewFile(name string, data []byte) File {
detected := mimetype.Detect(data)
return File{
ID: uuid.New(),
Name: name,
MimeType: detected.String(),
Size: int64(len(data)),
Data: data,
Created: time.Now(),
}
}
type File struct {
ID uuid.UUID
Name string
MimeType string
Size int64
Data []byte
Created time.Time
}

99
entity/page.go Normal file
View File

@@ -0,0 +1,99 @@
package entity
import (
"context"
"fmt"
"sync"
"time"
"github.com/google/uuid"
)
type Processor interface {
Process(ctx context.Context, format Format, url string) Result
}
type Format uint8
const (
FormatHeaders Format = iota
FormatSingleFile
FormatPDF
)
type Status uint8
const (
StatusNew Status = iota
StatusProcessing
StatusDone
StatusFailed
StatusWithErrors
)
func NewPage(url string, description string, formats ...Format) *Page {
return &Page{
ID: uuid.New(),
URL: url,
Description: description,
Formats: formats,
Created: time.Now(),
Version: 1,
}
}
type Page struct {
ID uuid.UUID
URL string
Description string
Created time.Time
Formats []Format
Results Results
Version uint16
Status Status
}
func (p *Page) SetProcessing() {
p.Status = StatusProcessing
}
func (p *Page) Process(ctx context.Context, wg *sync.WaitGroup, processor Processor) {
defer wg.Done()
innerWG := sync.WaitGroup{}
innerWG.Add(len(p.Formats))
for _, format := range p.Formats {
go func(format Format) {
defer innerWG.Done()
defer func() {
if err := recover(); err != nil {
p.Results.Add(Result{Format: format, Err: fmt.Errorf("recovered from panic: %v", err)})
}
}()
result := processor.Process(ctx, format, p.URL)
p.Results.Add(result)
}(format)
}
var hasResultWithOutErrors bool
for _, result := range p.Results.Results() {
if result.Err != nil {
p.Status = StatusWithErrors
} else {
hasResultWithOutErrors = true
}
}
if !hasResultWithOutErrors {
p.Status = StatusFailed
}
if p.Status == StatusProcessing {
p.Status = StatusDone
}
innerWG.Wait()
}

39
entity/result.go Normal file
View File

@@ -0,0 +1,39 @@
package entity
import (
"sync"
"github.com/vmihailenco/msgpack/v5"
)
type Result struct {
Format Format
Err error
Files []File
}
type Results struct {
mu sync.RWMutex
results []Result
}
func (r *Results) MarshalMsgpack() ([]byte, error) {
return msgpack.Marshal(r.results)
}
func (r *Results) UnmarshalMsgpack(b []byte) error {
return msgpack.Unmarshal(b, r.results)
}
func (r *Results) Add(result Result) {
r.mu.Lock()
r.results = append(r.results, result)
r.mu.Unlock()
}
func (r *Results) Results() []Result {
r.mu.RLock()
defer r.mu.RUnlock()
return r.results
}