[server][img] Create functionality for copying imgs. Needs to be wired

This commit is contained in:
Abhishek Shroff
2025-09-04 18:24:05 +05:30
parent f5e4cb9806
commit 08453a2c99
7 changed files with 84 additions and 10 deletions

View File

@@ -135,6 +135,7 @@ func SetupCommand() {
client := steve.Initialize(db.Get(ctx), cfg.Steve, logger)
steve.RegisterWorker(client, &jobs.MigrateWorker{})
steve.RegisterWorker(client, &jobs.CopyImgsWorker{})
steve.RegisterWorker(client, &jobs.CopyContentsWorker{})
steve.RegisterWorker(client, &jobs.DeleteContentsWorker{})
}

View File

@@ -174,6 +174,7 @@ func (f txFileSystem) Copy(src Resource, target string, requestedID uuid.UUID, r
createResources := make([]insertResourcesFastParams, 0, len(tree))
var createVersions []insertResourceVersionsFastParams
var copyContents []jobs.CopyContentsArgs
var copyImgs []jobs.CopyImgsArgs
var migrateContents []jobs.MigrateArgs
newIDs := make(map[uuid.UUID]uuid.UUID)
@@ -204,6 +205,7 @@ func (f txFileSystem) Copy(src Resource, target string, requestedID uuid.UUID, r
Size: int32(src.latestVersionInfo.Size),
MimeType: src.latestVersionInfo.MimeType,
SHA256: src.latestVersionInfo.SHA256,
ImgRes: src.latestVersionInfo.ImgRes,
})
v := []VersionInfo{{
ID: versionID,
@@ -211,8 +213,14 @@ func (f txFileSystem) Copy(src Resource, target string, requestedID uuid.UUID, r
Size: src.latestVersionInfo.Size,
MimeType: src.latestVersionInfo.MimeType,
SHA256: src.latestVersionInfo.SHA256,
ImgRes: src.latestVersionInfo.ImgRes,
}}
dest.versions, _ = json.Marshal(v)
copyImgs = append(copyImgs, jobs.CopyImgsArgs{
Src: src.latestVersionInfo.ID,
Dest: versionID,
ImgRes: src.latestVersionInfo.ImgRes,
})
copyContents = append(copyContents, jobs.CopyContentsArgs{
Src: src.latestVersionInfo.ID,
Dest: versionID,
@@ -243,6 +251,16 @@ func (f txFileSystem) Copy(src Resource, target string, requestedID uuid.UUID, r
Size: int32(src.latestVersionInfo.Size),
MimeType: src.latestVersionInfo.MimeType,
SHA256: src.latestVersionInfo.SHA256,
ImgRes: src.latestVersionInfo.ImgRes,
})
copyImgs = append(copyImgs, jobs.CopyImgsArgs{
Src: src.latestVersionInfo.ID,
Dest: versionID,
ImgRes: src.latestVersionInfo.ImgRes,
})
copyContents = append(copyContents, jobs.CopyContentsArgs{
Src: src.latestVersionInfo.ID,
Dest: versionID,
})
migrateContents = append(migrateContents, jobs.MigrateArgs{
VersionID: versionID,
@@ -265,6 +283,9 @@ func (f txFileSystem) Copy(src Resource, target string, requestedID uuid.UUID, r
}
}
if err := jobs.CopyImgsMany(f.db, copyImgs); err != nil {
return Resource{}, false, err
}
if err := jobs.CopyContents(f.db, copyContents); err != nil {
return Resource{}, false, err
}

View File

@@ -67,7 +67,7 @@ func (f *FileSystem) CreateFileByPath(path string, requestedID, versionID uuid.U
} else {
return computeProps(dest, func(len int, hash hash.Hash, mimeType string) error {
sum := hex.EncodeToString(hash.Sum(nil))
var generated int8
var generated uint8
if generated, err = imgr.Generate(backend.Path(versionID.String()), mimeType); err != nil {
return err
}
@@ -114,7 +114,7 @@ func (f *FileSystem) CreateFileVersion(r Resource, versionID uuid.UUID) (io.Writ
} else {
return computeProps(dest, func(len int, hash hash.Hash, mimeType string) error {
sum := hex.EncodeToString(hash.Sum(nil))
var generated int8
var generated uint8
if generated, err = imgr.Generate(backend.Path(versionID.String()), mimeType); err != nil {
return err
}
@@ -374,7 +374,7 @@ func updateResourceModified(db db.TxHandler, id uuid.UUID) error {
return err
}
func insertResourceVersion(db db.TxHandler, id, versionID uuid.UUID, size int64, mimeType, sha256 string, imgres int8) error {
func insertResourceVersion(db db.TxHandler, id, versionID uuid.UUID, size int64, mimeType, sha256 string, imgres uint8) error {
const q = `INSERT INTO resource_versions(id, resource_id, size, mime_type, sha256, storage, imgres)
VALUES (@version_id, @resource_id, @size, @mime_type, @sha256, @storage, @imgres)`
@@ -438,7 +438,7 @@ func (r iteratorForInsertResourcesFast) Err() error {
}
func insertResourceVersionsFast(db db.TxHandler, arg []insertResourceVersionsFastParams) (int64, error) {
return db.CopyFrom([]string{"resource_versions"}, []string{"id", "resource_id", "size", "mime_type", "sha256", "storage"}, &iteratorForInsertResourceVersionsFast{rows: arg})
return db.CopyFrom([]string{"resource_versions"}, []string{"id", "resource_id", "size", "mime_type", "sha256", "imgres", "storage"}, &iteratorForInsertResourceVersionsFast{rows: arg})
}
// For bulk insert
@@ -448,6 +448,7 @@ type insertResourceVersionsFastParams struct {
Size int32
MimeType string
SHA256 string
ImgRes uint8
}
// iteratorForInsertResourceVersionsFast implements pgx.CopyFromSource.
@@ -475,6 +476,7 @@ func (r iteratorForInsertResourceVersionsFast) Values() ([]interface{}, error) {
r.rows[0].Size,
r.rows[0].MimeType,
r.rows[0].SHA256,
r.rows[0].ImgRes,
storage.DefaultBackendName,
}, nil
}

View File

@@ -19,7 +19,7 @@ type VersionInfo struct {
Size int64 `json:"size"`
MimeType string `json:"mime_type"`
SHA256 string `json:"sha256"`
ImgRes int8 `json:"imgres"`
ImgRes uint8 `json:"imgres"`
}
type Version struct {

View File

@@ -41,7 +41,18 @@ func (g *Imgr) Open(id string, res Res) (io.ReadCloser, error) {
return os.Open(filepath.Join(g.dir, id) + "-" + resSuffixes[res] + ".webp")
}
func (g *Imgr) Generate(path, mimeType string) (int8, error) {
func (g *Imgr) Copy(src, dest string, res Res) error {
if in, err := os.Open(filepath.Join(g.dir, src) + "-" + resSuffixes[res] + ".webp"); err != nil {
return err
} else if out, err := os.Create(filepath.Join(g.dir, src) + "-" + resSuffixes[res] + ".webp"); err != nil {
return err
} else if _, err := io.Copy(out, in); err != nil {
return err
}
return nil
}
func (g *Imgr) Generate(path, mimeType string) (Res, error) {
if imageType, ok := strings.CutPrefix(mimeType, "image/"); ok {
if _, ok := imageTypes[imageType]; ok {
return g.processImage(path)
@@ -70,7 +81,7 @@ func (g *Imgr) Generate(path, mimeType string) (int8, error) {
// processImage generates preview + thumbnail for images (and PDF).
// Preview is only generated if the image size is larger than 1M
func (g *Imgr) processImage(input string) (int8, error) {
func (g *Imgr) processImage(input string) (Res, error) {
var generated Res
stat, err := os.Stat(input)
if err != nil {
@@ -96,7 +107,7 @@ func (g *Imgr) processImage(input string) (int8, error) {
// Generate thumbnail only for text using.
// A temporary document preview must be generated and then resized down
func (g *Imgr) processText(input string) (int8, error) {
func (g *Imgr) processText(input string) (Res, error) {
if err := generateTextPreview(input, g.tmp); err != nil {
return 0, err
}
@@ -113,7 +124,7 @@ func (g *Imgr) processText(input string) (int8, error) {
}
// Generate preview and thumbnail for office documents.
func (g *Imgr) processDocument(input string) (int8, error) {
func (g *Imgr) processDocument(input string) (Res, error) {
if err := generateDocumentPreview(input, g.dir); err != nil {
return 0, err
}

View File

@@ -8,7 +8,7 @@ import (
"strconv"
)
type Res = int8
type Res = uint8
const (
ResThumbnail Res = 1

View File

@@ -0,0 +1,39 @@
package jobs
import (
"context"
"codeberg.org/shroff/phylum/server/internal/db"
"codeberg.org/shroff/phylum/server/internal/steve"
"github.com/google/uuid"
)
type CopyImgsArgs struct {
Src uuid.UUID `json:"src"`
Dest uuid.UUID `json:"dest"`
ImgRes uint8 `json:"imgres"`
}
func (a CopyImgsArgs) Kind() string { return "copy_imgs" }
func (a CopyImgsArgs) Sequences() []string { return []string{a.Src.String(), a.Dest.String()} }
type CopyImgsWorker struct {
steve.WorkerDefaults[CopyImgsArgs]
}
func (w *CopyImgsWorker) Work(ctx context.Context, job *steve.Job[CopyImgsArgs]) error {
return copyImgs(ctx, job.Args.Src, job.Args.Dest, job.Args.ImgRes)
}
func CopyImgsMany(db db.Handler, args []CopyImgsArgs) error {
params := make([]steve.JobArgs, len(args))
for i, a := range args {
params[i] = a
}
return steve.Get().InsertJobs(db, params)
}
func copyImgs(ctx context.Context, src, dest uuid.UUID, imgRes uint8) error {
// TODO: implement
return nil
}