changed procedure of package metadata ejection, removed unnecessary fields and unnecessary string conversions

This commit is contained in:
dancheg97 2023-06-26 12:28:14 +03:00
parent 1d1a5a312f
commit f1fae9ada6

View File

@ -10,13 +10,11 @@ import (
"crypto/md5" "crypto/md5"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/mholt/archiver/v3" "github.com/mholt/archiver/v3"
) )
@ -29,14 +27,11 @@ type Metadata struct {
Version string Version string
Description string Description string
CompressedSize int64 CompressedSize int64
CompressedSizeMib string
InstalledSize int64 InstalledSize int64
InstalledSizeMib string
MD5 string MD5 string
SHA256 string SHA256 string
URL string URL string
BuildDate int64 BuildDate int64
BuildDateStr string
BaseDomain string BaseDomain string
Packager string Packager string
Provides []string Provides []string
@ -51,100 +46,89 @@ type Metadata struct {
// Function that recieves arch package archive data and returns it's metadata. // Function that recieves arch package archive data and returns it's metadata.
func EjectMetadata(filename, domain string, pkg []byte) (*Metadata, error) { func EjectMetadata(filename, domain string, pkg []byte) (*Metadata, error) {
pkgreader := io.LimitReader(bytes.NewReader(pkg), 250000) pkginfo, err := getPkginfo(pkg)
var buf bytes.Buffer
err := archiver.DefaultZstd.Decompress(pkgreader, &buf)
if err != nil { if err != nil {
if !errors.Is(err, io.ErrUnexpectedEOF) {
return nil, err return nil, err
} }
} var md = Metadata{
splt := strings.Split(buf.String(), "PKGINFO")
if len(splt) < 2 {
return nil, errors.New("unable to eject .PKGINFO from archive")
}
raw := splt[1][0:10000]
inssize := int64(len(pkg))
compsize := ejectInt64(raw, "size")
unixbuilddate := ejectInt64(raw, "builddate")
return &Metadata{
Filename: filename, Filename: filename,
Name: ejectString(raw, "pkgname"), BaseDomain: domain,
Base: ejectString(raw, "pkgbase"), CompressedSize: int64(len(pkg)),
Version: ejectString(raw, "pkgver"),
Description: ejectString(raw, "pkgdesc"),
CompressedSize: inssize,
CompressedSizeMib: ByteCountSI(inssize),
InstalledSize: compsize,
InstalledSizeMib: ByteCountSI(compsize),
MD5: md5sum(pkg), MD5: md5sum(pkg),
SHA256: sha256sum(pkg), SHA256: sha256sum(pkg),
URL: ejectString(raw, "url"),
BuildDate: unixbuilddate,
BuildDateStr: ReadableTime(unixbuilddate),
BaseDomain: domain,
Packager: ejectString(raw, "packager"),
Provides: ejectStrings(raw, "provides"),
License: ejectStrings(raw, "license"),
Arch: ejectStrings(raw, "arch"),
Depends: ejectStrings(raw, "depend"),
OptDepends: ejectStrings(raw, "optdepend"),
MakeDepends: ejectStrings(raw, "makedepend"),
CheckDepends: ejectStrings(raw, "checkdepend"),
Backup: ejectStrings(raw, "backup"),
}, nil
} }
for _, line := range strings.Split(pkginfo, "\n") {
func ejectString(raw, field string) string { splt := strings.Split(line, " = ")
splitted := strings.Split(raw, "\n"+field+" = ") if len(splt) != 2 {
if len(splitted) < 2 {
return ``
}
return strings.Split(splitted[1], "\n")[0]
}
func ejectStrings(raw, field string) []string {
splitted := strings.Split(raw, "\n"+field+" = ")
if len(splitted) < 2 {
return nil
}
var rez []string
for i, v := range splitted {
if i == 0 {
continue continue
} }
rez = append(rez, strings.Split(v, "\n")[0]) switch splt[0] {
} case "pkgname":
return rez md.Name = splt[1]
} case "pkgbase":
md.Base = splt[1]
func ejectInt64(raw, field string) int64 { case "pkgver":
splitted := strings.Split(raw, "\n"+field+" = ") md.Version = splt[1]
if len(splitted) < 2 { case "pkgdesc":
return 0 md.Description = splt[1]
} case "url":
i, err := strconv.ParseInt(strings.Split(splitted[1], "\n")[0], 10, 64) md.URL = splt[1]
case "packager":
md.Packager = splt[1]
case "builddate":
num, err := strconv.ParseInt(splt[1], 10, 64)
if err != nil { if err != nil {
return 0 return nil, err
} }
return i md.BuildDate = num
case "size":
num, err := strconv.ParseInt(splt[1], 10, 64)
if err != nil {
return nil, err
}
md.InstalledSize = num
case "provides":
md.Provides = append(md.Provides, splt[1])
case "license":
md.License = append(md.License, splt[1])
case "arch":
md.Arch = append(md.Arch, splt[1])
case "depend":
md.Depends = append(md.Depends, splt[1])
case "optdepend":
md.Depends = append(md.OptDepends, splt[1])
case "makedepend":
md.Depends = append(md.MakeDepends, splt[1])
case "checkdepend":
md.Depends = append(md.CheckDepends, splt[1])
case "backup":
md.Depends = append(md.Backup, splt[1])
}
}
return &md, nil
} }
func ByteCountSI(b int64) string { func getPkginfo(data []byte) (string, error) {
const unit = 1000 pkgreader := io.LimitReader(bytes.NewReader(data), 250000)
if b < unit { zstd := archiver.NewTarZstd()
return fmt.Sprintf("%d B", b) err := zstd.Open(pkgreader, int64(250000))
if err != nil {
return ``, err
} }
div, exp := int64(unit), 0 for {
for n := b / unit; n >= unit; n /= unit { f, err := zstd.Read()
div *= unit if err != nil {
exp++ return ``, err
} }
return fmt.Sprintf("%.1f %cB", float64(b)/float64(div), "kMGTPE"[exp]) if f.Name() != ".PKGINFO" {
continue
}
b, err := io.ReadAll(f)
if err != nil {
return ``, err
}
return string(b), nil
} }
func ReadableTime(unix int64) string {
return time.Unix(unix, 0).Format(time.DateTime)
} }
func md5sum(data []byte) string { func md5sum(data []byte) string {