mirror of
https://github.com/derfenix/webarchive.git
synced 2026-03-11 12:41:54 +03:00
Initial commit
This commit is contained in:
30
entity/file.go
Normal file
30
entity/file.go
Normal 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
99
entity/page.go
Normal 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
39
entity/result.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user