feat: wip directory metadata
This commit is contained in:
parent
eed785e1eb
commit
c2ed126ab8
|
@ -0,0 +1,92 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/serialize"
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
||||||
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DirectoryMetadata struct {
|
||||||
|
Details DirectoryMetadataDetails `json:"details"`
|
||||||
|
Directories map[string]DirectoryReference `json:"directories"`
|
||||||
|
Files map[string]FileReference `json:"files"`
|
||||||
|
ExtraMetadata ExtraMetadata `json:"extraMetadata"`
|
||||||
|
BaseMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ SerializableMetadata = (*DirectoryMetadata)(nil)
|
||||||
|
|
||||||
|
func NewDirectoryMetadata(details DirectoryMetadataDetails, directories map[string]DirectoryReference, files map[string]FileReference, extraMetadata ExtraMetadata) *DirectoryMetadata {
|
||||||
|
dirMetadata := &DirectoryMetadata{
|
||||||
|
Details: details,
|
||||||
|
Directories: directories,
|
||||||
|
Files: files,
|
||||||
|
ExtraMetadata: extraMetadata,
|
||||||
|
}
|
||||||
|
|
||||||
|
dirMetadata.Type = "directory"
|
||||||
|
return dirMetadata
|
||||||
|
}
|
||||||
|
func (dm *DirectoryMetadata) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
err := serialize.InitMarshaller(types.MetadataTypeDirectory, enc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
items := make([]interface{}, 4)
|
||||||
|
|
||||||
|
items[0] = dm.Details
|
||||||
|
items[1] = dm.Directories
|
||||||
|
items[2] = dm.Files
|
||||||
|
items[3] = dm.ExtraMetadata.Data
|
||||||
|
|
||||||
|
return enc.Encode(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dm *DirectoryMetadata) DecodeMsgpack(dec *msgpack.Decoder) error {
|
||||||
|
err := serialize.InitUnmarshaller(types.MetadataTypeDirectory, dec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
val, err := dec.DecodeArrayLen()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if val != 4 {
|
||||||
|
return errors.New(" Corrupted metadata")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < val; i++ {
|
||||||
|
switch i {
|
||||||
|
case 0:
|
||||||
|
err = dec.Decode(&dm.Details)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
err = dec.Decode(&dm.Directories)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
err = dec.Decode(&dm.Files)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
intMap, err := decodeIntMap(dec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dm.ExtraMetadata.Data = intMap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dm.Type = "directory"
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import "github.com/vmihailenco/msgpack/v5"
|
||||||
|
|
||||||
|
type DirectoryMetadataDetails struct {
|
||||||
|
Data map[int]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDirectoryMetadataDetails(data map[int]interface{}) *DirectoryMetadataDetails {
|
||||||
|
return &DirectoryMetadataDetails{
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dmd *DirectoryMetadataDetails) IsShared() bool {
|
||||||
|
_, exists := dmd.Data[3]
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dmd *DirectoryMetadataDetails) IsSharedReadOnly() bool {
|
||||||
|
value, exists := dmd.Data[3].([]interface{})
|
||||||
|
if !exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return len(value) > 1 && value[1] == true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dmd *DirectoryMetadataDetails) IsSharedReadWrite() bool {
|
||||||
|
value, exists := dmd.Data[3].([]interface{})
|
||||||
|
if !exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return len(value) > 2 && value[2] == true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dmd *DirectoryMetadataDetails) SetShared(value bool, write bool) {
|
||||||
|
if dmd.Data == nil {
|
||||||
|
dmd.Data = make(map[int]interface{})
|
||||||
|
}
|
||||||
|
sharedValue, exists := dmd.Data[3].([]interface{})
|
||||||
|
if !exists {
|
||||||
|
sharedValue = make([]interface{}, 3)
|
||||||
|
dmd.Data[3] = sharedValue
|
||||||
|
}
|
||||||
|
if write {
|
||||||
|
sharedValue[2] = value
|
||||||
|
} else {
|
||||||
|
sharedValue[1] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (dmd *DirectoryMetadataDetails) DecodeMsgpack(dec *msgpack.Decoder) error {
|
||||||
|
mapLen, err := dec.DecodeMapLen()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < mapLen; i++ {
|
||||||
|
key, err := dec.DecodeInt8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
value, err := dec.DecodeInterface()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dmd.Data[int(key)] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dmd DirectoryMetadataDetails) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
return enc.Encode(dmd.Data)
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import "github.com/vmihailenco/msgpack/v5"
|
||||||
|
|
||||||
|
var _ SerializableMetadata = (*DirectoryReference)(nil)
|
||||||
|
|
||||||
|
type DirectoryReference struct {
|
||||||
|
Created uint64 `json:"created"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
EncryptedWriteKey Base64UrlBinary `json:"encryptedWriteKey,string"`
|
||||||
|
PublicKey Base64UrlBinary `json:"publicKey,string"`
|
||||||
|
EncryptionKey Base64UrlBinary `json:"encryptionKey,string"`
|
||||||
|
Ext map[string]interface{} `json:"ext"`
|
||||||
|
URI string `json:"uri"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDirectoryReference(created uint64, name string, encryptedWriteKey, publicKey, encryptionKey []byte, ext map[string]interface{}) *DirectoryReference {
|
||||||
|
return &DirectoryReference{
|
||||||
|
Created: created,
|
||||||
|
Name: name,
|
||||||
|
EncryptedWriteKey: encryptedWriteKey,
|
||||||
|
PublicKey: publicKey,
|
||||||
|
EncryptionKey: encryptionKey,
|
||||||
|
Ext: ext,
|
||||||
|
URI: "",
|
||||||
|
Key: "",
|
||||||
|
Size: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dr *DirectoryReference) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
data := map[int]interface{}{
|
||||||
|
1: dr.Name,
|
||||||
|
2: dr.Created,
|
||||||
|
3: dr.PublicKey,
|
||||||
|
4: dr.EncryptedWriteKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
if dr.EncryptionKey != nil {
|
||||||
|
data[5] = dr.EncryptionKey
|
||||||
|
}
|
||||||
|
|
||||||
|
if dr.Ext != nil {
|
||||||
|
data[6] = dr.Ext
|
||||||
|
}
|
||||||
|
|
||||||
|
return enc.Encode(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dr *DirectoryReference) DecodeMsgpack(dec *msgpack.Decoder) error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
l int
|
||||||
|
)
|
||||||
|
if l, err = dec.DecodeMapLen(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
key, err := dec.DecodeInt8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
value, err := dec.DecodeInterface()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch key {
|
||||||
|
case int8(1):
|
||||||
|
dr.Name = value.(string)
|
||||||
|
case int8(2):
|
||||||
|
dr.Created = value.(uint64)
|
||||||
|
case int8(3):
|
||||||
|
dr.PublicKey = value.([]byte)
|
||||||
|
case int8(4):
|
||||||
|
dr.EncryptedWriteKey = value.([]byte)
|
||||||
|
case int8(5):
|
||||||
|
dr.EncryptionKey = value.([]byte)
|
||||||
|
case int8(6):
|
||||||
|
dr.Ext = value.(map[string]interface{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,514 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
|
cmp "github.com/LumeWeb/go-cmp"
|
||||||
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func readFile(filename string) []byte {
|
||||||
|
filePath := filepath.Join("testdata", filename)
|
||||||
|
data, err := os.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDirectoryMeta() *DirectoryMetadata {
|
||||||
|
data := readFile("directory.json")
|
||||||
|
|
||||||
|
var dir DirectoryMetadata
|
||||||
|
|
||||||
|
err := json.Unmarshal(data, &dir)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &dir
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDirectoryMetadata_DecodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Details DirectoryMetadataDetails
|
||||||
|
Directories map[string]DirectoryReference
|
||||||
|
Files map[string]FileReference
|
||||||
|
ExtraMetadata ExtraMetadata
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Decode",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
jsonDm := getDirectoryMeta()
|
||||||
|
dm := &DirectoryMetadata{}
|
||||||
|
|
||||||
|
if err := msgpack.Unmarshal(readFile("directory.bin"), dm); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("DecodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(cmp.Diff(jsonDm, dm))
|
||||||
|
if !cmp.Equal(jsonDm, dm) {
|
||||||
|
t.Errorf("DecodeMsgpack() error = %v, wantErr %v", "msgpack does not match json", tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDirectoryMetadata_EncodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Details DirectoryMetadataDetails
|
||||||
|
Directories map[string]DirectoryReference
|
||||||
|
Files map[string]FileReference
|
||||||
|
ExtraMetadata ExtraMetadata
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
enc *msgpack.Encoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
dm := &DirectoryMetadata{
|
||||||
|
Details: tt.fields.Details,
|
||||||
|
Directories: tt.fields.Directories,
|
||||||
|
Files: tt.fields.Files,
|
||||||
|
ExtraMetadata: tt.fields.ExtraMetadata,
|
||||||
|
}
|
||||||
|
if err := dm.EncodeMsgpack(tt.args.enc); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("EncodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDirectoryReference_DecodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Created uint64
|
||||||
|
Name string
|
||||||
|
EncryptedWriteKey []byte
|
||||||
|
PublicKey []byte
|
||||||
|
EncryptionKey []byte
|
||||||
|
Ext map[string]interface{}
|
||||||
|
URI string
|
||||||
|
Key string
|
||||||
|
Size int64
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
dec *msgpack.Decoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
dr := &DirectoryReference{
|
||||||
|
Created: tt.fields.Created,
|
||||||
|
Name: tt.fields.Name,
|
||||||
|
EncryptedWriteKey: tt.fields.EncryptedWriteKey,
|
||||||
|
PublicKey: tt.fields.PublicKey,
|
||||||
|
EncryptionKey: tt.fields.EncryptionKey,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
URI: tt.fields.URI,
|
||||||
|
Key: tt.fields.Key,
|
||||||
|
Size: tt.fields.Size,
|
||||||
|
}
|
||||||
|
if err := dr.DecodeMsgpack(tt.args.dec); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("DecodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDirectoryReference_EncodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Created uint64
|
||||||
|
Name string
|
||||||
|
EncryptedWriteKey []byte
|
||||||
|
PublicKey []byte
|
||||||
|
EncryptionKey []byte
|
||||||
|
Ext map[string]interface{}
|
||||||
|
URI string
|
||||||
|
Key string
|
||||||
|
Size int64
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
enc *msgpack.Encoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
dr := &DirectoryReference{
|
||||||
|
Created: tt.fields.Created,
|
||||||
|
Name: tt.fields.Name,
|
||||||
|
EncryptedWriteKey: tt.fields.EncryptedWriteKey,
|
||||||
|
PublicKey: tt.fields.PublicKey,
|
||||||
|
EncryptionKey: tt.fields.EncryptionKey,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
URI: tt.fields.URI,
|
||||||
|
Key: tt.fields.Key,
|
||||||
|
Size: tt.fields.Size,
|
||||||
|
}
|
||||||
|
if err := dr.EncodeMsgpack(tt.args.enc); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("EncodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileReference_DecodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Name string
|
||||||
|
Created int
|
||||||
|
Version int
|
||||||
|
File *FileVersion
|
||||||
|
Ext map[string]interface{}
|
||||||
|
History map[int]*FileVersion
|
||||||
|
MimeType string
|
||||||
|
URI string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
dec *msgpack.Decoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fr := &FileReference{
|
||||||
|
Name: tt.fields.Name,
|
||||||
|
Created: tt.fields.Created,
|
||||||
|
Version: tt.fields.Version,
|
||||||
|
File: tt.fields.File,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
History: tt.fields.History,
|
||||||
|
MimeType: tt.fields.MimeType,
|
||||||
|
URI: tt.fields.URI,
|
||||||
|
Key: tt.fields.Key,
|
||||||
|
}
|
||||||
|
if err := fr.DecodeMsgpack(tt.args.dec); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("DecodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileReference_EncodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Name string
|
||||||
|
Created int
|
||||||
|
Version int
|
||||||
|
File *FileVersion
|
||||||
|
Ext map[string]interface{}
|
||||||
|
History map[int]*FileVersion
|
||||||
|
MimeType string
|
||||||
|
URI string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
enc *msgpack.Encoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fr := &FileReference{
|
||||||
|
Name: tt.fields.Name,
|
||||||
|
Created: tt.fields.Created,
|
||||||
|
Version: tt.fields.Version,
|
||||||
|
File: tt.fields.File,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
History: tt.fields.History,
|
||||||
|
MimeType: tt.fields.MimeType,
|
||||||
|
URI: tt.fields.URI,
|
||||||
|
Key: tt.fields.Key,
|
||||||
|
}
|
||||||
|
if err := fr.EncodeMsgpack(tt.args.enc); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("EncodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileReference_Modified(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Name string
|
||||||
|
Created int
|
||||||
|
Version int
|
||||||
|
File *FileVersion
|
||||||
|
Ext map[string]interface{}
|
||||||
|
History map[int]*FileVersion
|
||||||
|
MimeType string
|
||||||
|
URI string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
want int
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fr := &FileReference{
|
||||||
|
Name: tt.fields.Name,
|
||||||
|
Created: tt.fields.Created,
|
||||||
|
Version: tt.fields.Version,
|
||||||
|
File: tt.fields.File,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
History: tt.fields.History,
|
||||||
|
MimeType: tt.fields.MimeType,
|
||||||
|
URI: tt.fields.URI,
|
||||||
|
Key: tt.fields.Key,
|
||||||
|
}
|
||||||
|
if got := fr.Modified(); got != tt.want {
|
||||||
|
t.Errorf("Modified() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileVersionThumbnail_DecodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
ImageType string
|
||||||
|
AspectRatio float64
|
||||||
|
CID *encoding.EncryptedCID
|
||||||
|
Thumbhash []byte
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
dec *msgpack.Decoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fvt := &FileVersionThumbnail{
|
||||||
|
ImageType: tt.fields.ImageType,
|
||||||
|
AspectRatio: tt.fields.AspectRatio,
|
||||||
|
CID: tt.fields.CID,
|
||||||
|
Thumbhash: tt.fields.Thumbhash,
|
||||||
|
}
|
||||||
|
if err := fvt.DecodeMsgpack(tt.args.dec); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("DecodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileVersionThumbnail_Encode(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
ImageType string
|
||||||
|
AspectRatio float64
|
||||||
|
CID *encoding.EncryptedCID
|
||||||
|
Thumbhash []byte
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
want map[int]interface{}
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fvt := &FileVersionThumbnail{
|
||||||
|
ImageType: tt.fields.ImageType,
|
||||||
|
AspectRatio: tt.fields.AspectRatio,
|
||||||
|
CID: tt.fields.CID,
|
||||||
|
Thumbhash: tt.fields.Thumbhash,
|
||||||
|
}
|
||||||
|
if got := fvt.Encode(); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("Encode() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileVersionThumbnail_EncodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
ImageType string
|
||||||
|
AspectRatio float64
|
||||||
|
CID *encoding.EncryptedCID
|
||||||
|
Thumbhash []byte
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
enc *msgpack.Encoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fvt := &FileVersionThumbnail{
|
||||||
|
ImageType: tt.fields.ImageType,
|
||||||
|
AspectRatio: tt.fields.AspectRatio,
|
||||||
|
CID: tt.fields.CID,
|
||||||
|
Thumbhash: tt.fields.Thumbhash,
|
||||||
|
}
|
||||||
|
if err := fvt.EncodeMsgpack(tt.args.enc); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("EncodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileVersion_CID(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Ts int
|
||||||
|
EncryptedCID *encoding.EncryptedCID
|
||||||
|
PlaintextCID *encoding.CID
|
||||||
|
Thumbnail *FileVersionThumbnail
|
||||||
|
Hashes []*encoding.Multihash
|
||||||
|
Ext map[string]interface{}
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
want *encoding.CID
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fv := &FileVersion{
|
||||||
|
Ts: tt.fields.Ts,
|
||||||
|
EncryptedCID: tt.fields.EncryptedCID,
|
||||||
|
PlaintextCID: tt.fields.PlaintextCID,
|
||||||
|
Thumbnail: tt.fields.Thumbnail,
|
||||||
|
Hashes: tt.fields.Hashes,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
}
|
||||||
|
if got := fv.CID(); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("CID() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileVersion_DecodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Ts int
|
||||||
|
EncryptedCID *encoding.EncryptedCID
|
||||||
|
PlaintextCID *encoding.CID
|
||||||
|
Thumbnail *FileVersionThumbnail
|
||||||
|
Hashes []*encoding.Multihash
|
||||||
|
Ext map[string]interface{}
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
dec *msgpack.Decoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fv := &FileVersion{
|
||||||
|
Ts: tt.fields.Ts,
|
||||||
|
EncryptedCID: tt.fields.EncryptedCID,
|
||||||
|
PlaintextCID: tt.fields.PlaintextCID,
|
||||||
|
Thumbnail: tt.fields.Thumbnail,
|
||||||
|
Hashes: tt.fields.Hashes,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
}
|
||||||
|
if err := fv.DecodeMsgpack(tt.args.dec); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("DecodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileVersion_EncodeMsgpack(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Ts int
|
||||||
|
EncryptedCID *encoding.EncryptedCID
|
||||||
|
PlaintextCID *encoding.CID
|
||||||
|
Thumbnail *FileVersionThumbnail
|
||||||
|
Hashes []*encoding.Multihash
|
||||||
|
Ext map[string]interface{}
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
enc *msgpack.Encoder
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
// TODO: Add test cases.
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
fv := &FileVersion{
|
||||||
|
Ts: tt.fields.Ts,
|
||||||
|
EncryptedCID: tt.fields.EncryptedCID,
|
||||||
|
PlaintextCID: tt.fields.PlaintextCID,
|
||||||
|
Thumbnail: tt.fields.Thumbnail,
|
||||||
|
Hashes: tt.fields.Hashes,
|
||||||
|
Ext: tt.fields.Ext,
|
||||||
|
}
|
||||||
|
if err := fv.EncodeMsgpack(tt.args.enc); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("EncodeMsgpack() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
||||||
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExtraMetadata struct {
|
||||||
|
Data map[int]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewExtraMetadata(data map[int]interface{}) *ExtraMetadata {
|
||||||
|
return &ExtraMetadata{
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (em *ExtraMetadata) ToJSON() map[string]interface{} {
|
||||||
|
jsonObject := make(map[string]interface{})
|
||||||
|
names := map[types.MetadataExtension]string{
|
||||||
|
types.MetadataExtensionLicenses: "licenses",
|
||||||
|
types.MetadataExtensionDonationKeys: "donationKeys",
|
||||||
|
types.MetadataExtensionWikidataClaims: "wikidataClaims",
|
||||||
|
types.MetadataExtensionLanguages: "languages",
|
||||||
|
types.MetadataExtensionSourceUris: "sourceUris",
|
||||||
|
types.MetadataExtensionPreviousVersions: "previousVersions",
|
||||||
|
types.MetadataExtensionTimestamp: "timestamp",
|
||||||
|
types.MetadataExtensionOriginalTimestamp: "originalTimestamp",
|
||||||
|
types.MetadataExtensionTags: "tags",
|
||||||
|
types.MetadataExtensionCategories: "categories",
|
||||||
|
types.MetadataExtensionBasicMediaMetadata: "basicMediaMetadata",
|
||||||
|
types.MetadataExtensionViewTypes: "viewTypes",
|
||||||
|
types.MetadataExtensionBridge: "bridge",
|
||||||
|
types.MetadataExtensionRoutingHints: "routingHints",
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range em.Data {
|
||||||
|
name, ok := names[types.MetadataExtension(key)]
|
||||||
|
if ok {
|
||||||
|
if types.MetadataExtension(key) == types.MetadataExtensionUpdateCID {
|
||||||
|
cid, err := encoding.CIDFromBytes(value.([]byte))
|
||||||
|
var cidString string
|
||||||
|
if err == nil {
|
||||||
|
cidString, err = cid.ToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
jsonObject["updateCID"] = cidString
|
||||||
|
} else {
|
||||||
|
jsonObject["updateCID"] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
jsonObject[name] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonObject
|
||||||
|
}
|
||||||
|
func (em *ExtraMetadata) DecodeMsgpack(dec *msgpack.Decoder) error {
|
||||||
|
mapLen, err := dec.DecodeMapLen()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < mapLen; i++ {
|
||||||
|
key, err := dec.DecodeInt8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
value, err := dec.DecodeInterface()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
em.Data[int(key)] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (em ExtraMetadata) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
return enc.Encode(em.Data)
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import "github.com/vmihailenco/msgpack/v5"
|
||||||
|
|
||||||
|
var _ SerializableMetadata = (*FileReference)(nil)
|
||||||
|
|
||||||
|
type FileReference struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Created int `json:"created"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
File *FileVersion `json:"file"`
|
||||||
|
Ext map[string]interface{} `json:"ext"`
|
||||||
|
History map[int]*FileVersion `json:"history"`
|
||||||
|
MimeType string `json:"mimeType"`
|
||||||
|
URI string `json:"uri"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileReference(name string, created, version int, file *FileVersion, ext map[string]interface{}, history map[int]*FileVersion, mimeType string) *FileReference {
|
||||||
|
return &FileReference{
|
||||||
|
Name: name,
|
||||||
|
Created: created,
|
||||||
|
Version: version,
|
||||||
|
File: file,
|
||||||
|
Ext: ext,
|
||||||
|
History: history,
|
||||||
|
MimeType: mimeType,
|
||||||
|
URI: "",
|
||||||
|
Key: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fr *FileReference) Modified() int {
|
||||||
|
return fr.File.Ts
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fr *FileReference) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
data := map[int]interface{}{
|
||||||
|
1: fr.Name,
|
||||||
|
2: fr.Created,
|
||||||
|
4: fr.File,
|
||||||
|
5: fr.Version,
|
||||||
|
}
|
||||||
|
|
||||||
|
if fr.MimeType != "" {
|
||||||
|
data[6] = fr.MimeType
|
||||||
|
}
|
||||||
|
|
||||||
|
if fr.Ext != nil {
|
||||||
|
data[7] = fr.Ext
|
||||||
|
}
|
||||||
|
|
||||||
|
if fr.History != nil {
|
||||||
|
historyData := make(map[int]interface{})
|
||||||
|
for key, value := range fr.History {
|
||||||
|
historyData[key] = value
|
||||||
|
}
|
||||||
|
data[8] = historyData
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (fr *FileReference) DecodeMsgpack(dec *msgpack.Decoder) error {
|
||||||
|
mapLen, err := dec.DecodeMapLen()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < mapLen; i++ {
|
||||||
|
key, err := dec.DecodeInt8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch key {
|
||||||
|
case int8(1):
|
||||||
|
err := dec.Decode(&fr.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(2):
|
||||||
|
err := dec.Decode(&fr.Created)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(4):
|
||||||
|
err := dec.Decode(&fr.File)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(5):
|
||||||
|
val, err := dec.DecodeInt()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fr.Version = val
|
||||||
|
case int8(6):
|
||||||
|
err := dec.Decode(&fr.MimeType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(7):
|
||||||
|
err := dec.Decode(&fr.Ext)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(8):
|
||||||
|
historyDataLen, err := dec.DecodeMapLen()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fr.History = make(map[int]*FileVersion, historyDataLen)
|
||||||
|
for range fr.History {
|
||||||
|
k, err := dec.DecodeInt()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileVersion FileVersion
|
||||||
|
err = dec.Decode(&fileVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fr.History[k] = &fileVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileVersion struct {
|
||||||
|
Ts int `json:"ts"`
|
||||||
|
EncryptedCID *encoding.EncryptedCID `json:"encryptedCID,string"`
|
||||||
|
PlaintextCID *encoding.CID `json:"plaintextCID,string"`
|
||||||
|
Thumbnail *FileVersionThumbnail `json:"thumbnail"`
|
||||||
|
Hashes []*encoding.Multihash `json:"hashes"`
|
||||||
|
Ext map[string]interface{} `json:"ext"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileVersion(ts int, encryptedCID *encoding.EncryptedCID, plaintextCID *encoding.CID, thumbnail *FileVersionThumbnail, hashes []*encoding.Multihash, ext map[string]interface{}) *FileVersion {
|
||||||
|
return &FileVersion{
|
||||||
|
Ts: ts,
|
||||||
|
EncryptedCID: encryptedCID,
|
||||||
|
PlaintextCID: plaintextCID,
|
||||||
|
Thumbnail: thumbnail,
|
||||||
|
Hashes: hashes,
|
||||||
|
Ext: ext,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fv *FileVersion) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
data := map[int]interface{}{
|
||||||
|
8: fv.Ts,
|
||||||
|
}
|
||||||
|
|
||||||
|
if fv.EncryptedCID != nil {
|
||||||
|
data[1] = fv.EncryptedCID.ToBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
if fv.PlaintextCID != nil {
|
||||||
|
data[2] = fv.PlaintextCID.ToBytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(fv.Hashes) > 0 {
|
||||||
|
hashesData := make([][]byte, len(fv.Hashes))
|
||||||
|
for i, hash := range fv.Hashes {
|
||||||
|
hashesData[i] = hash.FullBytes
|
||||||
|
}
|
||||||
|
data[9] = hashesData
|
||||||
|
}
|
||||||
|
|
||||||
|
if fv.Thumbnail != nil {
|
||||||
|
data[10] = fv.Thumbnail.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
return enc.Encode(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fv *FileVersion) DecodeMsgpack(dec *msgpack.Decoder) error {
|
||||||
|
mapLen, err := dec.DecodeMapLen()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < mapLen; i++ {
|
||||||
|
key, err := dec.DecodeInt8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch key {
|
||||||
|
|
||||||
|
case int8(1):
|
||||||
|
err := dec.Decode(&fv.EncryptedCID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
case int8(2):
|
||||||
|
err := dec.Decode(&fv.PlaintextCID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(8):
|
||||||
|
err := dec.Decode(&fv.Ts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(9):
|
||||||
|
hashesData, err := dec.DecodeSlice()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fv.Hashes = make([]*encoding.Multihash, len(hashesData))
|
||||||
|
for i, hashData := range hashesData {
|
||||||
|
hashBytes := hashData.([]byte)
|
||||||
|
fv.Hashes[i] = encoding.NewMultihash(hashBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
case int8(10):
|
||||||
|
err := dec.Decode(&fv.Thumbnail)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fv *FileVersion) CID() *encoding.CID {
|
||||||
|
if fv.PlaintextCID != nil {
|
||||||
|
return fv.PlaintextCID
|
||||||
|
}
|
||||||
|
return &fv.EncryptedCID.OriginalCID
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
||||||
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileVersionThumbnail struct {
|
||||||
|
ImageType string
|
||||||
|
AspectRatio float64
|
||||||
|
CID *encoding.EncryptedCID
|
||||||
|
Thumbhash []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileVersionThumbnail(imageType string, aspectRatio float64, cid *encoding.EncryptedCID, thumbhash []byte) *FileVersionThumbnail {
|
||||||
|
return &FileVersionThumbnail{
|
||||||
|
ImageType: imageType,
|
||||||
|
AspectRatio: aspectRatio,
|
||||||
|
CID: cid,
|
||||||
|
Thumbhash: thumbhash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fvt *FileVersionThumbnail) EncodeMsgpack(enc *msgpack.Encoder) error {
|
||||||
|
data := map[int]interface{}{
|
||||||
|
2: fvt.AspectRatio,
|
||||||
|
3: fvt.CID.ToBytes(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if fvt.ImageType != "" {
|
||||||
|
data[1] = fvt.ImageType
|
||||||
|
}
|
||||||
|
|
||||||
|
if fvt.Thumbhash != nil {
|
||||||
|
data[4] = fvt.Thumbhash
|
||||||
|
}
|
||||||
|
|
||||||
|
return enc.Encode(data)
|
||||||
|
}
|
||||||
|
func (fvt *FileVersionThumbnail) DecodeMsgpack(dec *msgpack.Decoder) error {
|
||||||
|
mapLen, err := dec.DecodeMapLen()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < mapLen; i++ {
|
||||||
|
key, err := dec.DecodeInt8()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch key {
|
||||||
|
case int8(1):
|
||||||
|
err := dec.Decode(&fvt.ImageType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(2):
|
||||||
|
err := dec.Decode(&fvt.AspectRatio)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case int8(3):
|
||||||
|
val, err := dec.DecodeBytes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fvt.CID, err = encoding.EncryptedCIDFromBytes(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
case int8(4):
|
||||||
|
err := dec.Decode(&fvt.Thumbhash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (fvt *FileVersionThumbnail) Encode() map[int]interface{} {
|
||||||
|
data := map[int]interface{}{
|
||||||
|
2: fvt.AspectRatio,
|
||||||
|
3: fvt.CID.ToBytes(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if fvt.ImageType != "" {
|
||||||
|
data[1] = fvt.ImageType
|
||||||
|
}
|
||||||
|
|
||||||
|
if fvt.Thumbhash != nil {
|
||||||
|
data[4] = fvt.Thumbhash
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import "github.com/vmihailenco/msgpack/v5"
|
||||||
|
|
||||||
|
type Metadata interface {
|
||||||
|
}
|
||||||
|
type SerializableMetadata interface {
|
||||||
|
msgpack.CustomEncoder
|
||||||
|
msgpack.CustomDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseMetadata struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package metadata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Base64UrlBinary []byte
|
||||||
|
|
||||||
|
func (b *Base64UrlBinary) UnmarshalJSON(data []byte) error {
|
||||||
|
strData := string(data)
|
||||||
|
if len(strData) >= 2 && strData[0] == '"' && strData[len(strData)-1] == '"' {
|
||||||
|
strData = strData[1 : len(strData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if strData == "null" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
decodedData, err := base64.RawURLEncoding.DecodeString(strData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*b = (decodedData)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (b Base64UrlBinary) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(base64.RawURLEncoding.EncodeToString(b)), nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeIntMap(dec *msgpack.Decoder) (map[int]interface{}, error) {
|
||||||
|
mapLen, err := dec.DecodeMapLen()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data := make(map[int]interface{}, mapLen)
|
||||||
|
|
||||||
|
for i := 0; i < mapLen; i++ {
|
||||||
|
key, err := dec.DecodeInt()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
value, err := dec.DecodeInterface()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,193 @@
|
||||||
|
{
|
||||||
|
"type": "directory",
|
||||||
|
"details": {},
|
||||||
|
"directories": {
|
||||||
|
"arch": {
|
||||||
|
"name": "arch",
|
||||||
|
"created": 1704127624979,
|
||||||
|
"publicKey": "7Vd1kAf0LoYmKKQ9-C8Znl0npyjK2M4-ciiNWShOTpbD",
|
||||||
|
"encryptedWriteKey": "",
|
||||||
|
"encryptionKey": null,
|
||||||
|
"ext": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"archlinux-bootstrap-x86_64.tar.gz": {
|
||||||
|
"name": "archlinux-bootstrap-x86_64.tar.gz",
|
||||||
|
"created": 1704127689514,
|
||||||
|
"modified": 1704127689514,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": null,
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127689514,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z6e5xDpewiueHz6n9HJz21uGmTDvvctawujzYSeu9773k8s9RkG8a",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-bootstrap-x86_64.tar.gz.sig": {
|
||||||
|
"name": "archlinux-bootstrap-x86_64.tar.gz.sig",
|
||||||
|
"created": 1704127698951,
|
||||||
|
"modified": 1704127698951,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "application/pgp-signature",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127698951,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z4odYNo3uQhHhypXze7ThLAKrnSGsJ3cRf1bYsvnt65Mqi9gp",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-x86_64.iso": {
|
||||||
|
"name": "archlinux-x86_64.iso",
|
||||||
|
"created": 1704127623412,
|
||||||
|
"modified": 1704127623412,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "application/x-iso9660-image",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127623412,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z6e5sRB3BeynWLyrzRPLWFetUS7PNDZWZHURnFAyikcRyGTnxjMwC",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-x86_64.iso.sig": {
|
||||||
|
"name": "archlinux-x86_64.iso.sig",
|
||||||
|
"created": 1704127698648,
|
||||||
|
"modified": 1704127698648,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "application/pgp-signature",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127698648,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z4odLKvhW8QPH4dLNqVzU1Zq6nj1MBdU6HYpJmThdzag4RJma",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-2024.01.01-x86_64.iso": {
|
||||||
|
"name": "archlinux-2024.01.01-x86_64.iso",
|
||||||
|
"created": 1704127623412,
|
||||||
|
"modified": 1704127623412,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "application/x-iso9660-image",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127623412,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z6e5sRB3BeynWLyrzRPLWFetUS7PNDZWZHURnFAyikcRyGTnxjMwC",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-2024.01.01-x86_64.iso.sig": {
|
||||||
|
"name": "archlinux-2024.01.01-x86_64.iso.sig",
|
||||||
|
"created": 1704127698648,
|
||||||
|
"modified": 1704127698648,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "application/pgp-signature",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127698648,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z4odLKvhW8QPH4dLNqVzU1Zq6nj1MBdU6HYpJmThdzag4RJma",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-2024.01.01-x86_64.iso.torrent": {
|
||||||
|
"name": "archlinux-2024.01.01-x86_64.iso.torrent",
|
||||||
|
"created": 1704127703578,
|
||||||
|
"modified": 1704127703578,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "application/x-bittorrent",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127703578,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "zHnmSZc3qDZMGfhNaZ6iVjkbxeVzMonKtAnTmBtRSwXy7RLYQK",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-bootstrap-2024.01.01-x86_64.tar.gz": {
|
||||||
|
"name": "archlinux-bootstrap-2024.01.01-x86_64.tar.gz",
|
||||||
|
"created": 1704127689514,
|
||||||
|
"modified": 1704127689514,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": null,
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127689514,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z6e5xDpewiueHz6n9HJz21uGmTDvvctawujzYSeu9773k8s9RkG8a",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"archlinux-bootstrap-2024.01.01-x86_64.tar.gz.sig": {
|
||||||
|
"name": "archlinux-bootstrap-2024.01.01-x86_64.tar.gz.sig",
|
||||||
|
"created": 1704127698951,
|
||||||
|
"modified": 1704127698951,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "application/pgp-signature",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127698951,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "z4odYNo3uQhHhypXze7ThLAKrnSGsJ3cRf1bYsvnt65Mqi9gp",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"b2sums.txt": {
|
||||||
|
"name": "b2sums.txt",
|
||||||
|
"created": 1704127703594,
|
||||||
|
"modified": 1704127703594,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "text/plain",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127703594,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "zHnoyywarEZHWrSMZjL55nXeMAPsYi1mhXQs7ZmWqkpSg5Auz1",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
},
|
||||||
|
"sha256sums.txt": {
|
||||||
|
"name": "sha256sums.txt",
|
||||||
|
"created": 1704127703591,
|
||||||
|
"modified": 1704127703591,
|
||||||
|
"version": 0,
|
||||||
|
"mimeType": "text/plain",
|
||||||
|
"file": {
|
||||||
|
"ts": 1704127703591,
|
||||||
|
"encryptedCID": null,
|
||||||
|
"cid": "zHnnZGvqwnoN2AE342zhrxGWnuJpv79esruhY259TkXYyqmPB6",
|
||||||
|
"hashes": null,
|
||||||
|
"thumbnail": null
|
||||||
|
},
|
||||||
|
"ext": null,
|
||||||
|
"history": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extraMetadata": {}
|
||||||
|
}
|
Loading…
Reference in New Issue