memoexport

package
v0.31.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 19, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package memoexport implements the Memos Export Format: a ZIP container that carries one user's memos and attachments between Memos instances.

The package owns the container layout, the JSON records, and the reading and writing rules defined in docs/design/memos-export-format.md. It has no opinion about how records map onto a Memos instance; transports call the Writer with data they have already loaded and interpret the records a Reader returns.

Index

Constants

View Source
const (
	// Format is the value of the manifest's format member.
	Format = "memos-export"

	// FormatVersion is the newest version this package writes.
	FormatVersion = "1.0"
	// FormatMajor is the major version this package reads.
	FormatMajor = 1
	// MediaType is the HTTP Content-Type of an export. It is deliberately not
	// stored inside the container: a leading "mimetype" entry makes macOS
	// Archive Utility treat the file as an unknown document package and
	// refuse to expand it.
	MediaType = "application/vnd.usememos.export+zip"

	// ManifestEntry holds the archive-level record and identifies the format.
	ManifestEntry = "manifest.json"
	// MemosDir holds one record and one content file per memo.
	MemosDir = "memos/"
	// AttachmentsDir holds attachment bytes under attachments/<uid>/<name>.
	AttachmentsDir = "attachments/"

	// ScopeKindUser is the only scope kind written in 1.0.
	ScopeKindUser = "USER"

	// RelationReference is the only relation type written in 1.0.
	RelationReference = "REFERENCE"
)

Variables

This section is empty.

Functions

func AttachmentPath

func AttachmentPath(uid, filename string) string

AttachmentPath is the entry name writers use for attachment bytes.

func ContentPath

func ContentPath(uid string) string

ContentPath is the entry name writers use for a memo's content.

func FormatTime

func FormatTime(unix int64) string

FormatTime renders a Unix timestamp as the archive's RFC 3339 UTC form.

func ParseTime

func ParseTime(value string) (int64, error)

ParseTime reads an archive timestamp. It accepts fractional seconds and any RFC 3339 offset, and returns the instant as Unix seconds.

func RecordPath

func RecordPath(uid string) string

RecordPath is the entry name of a memo record.

func SafeFilename

func SafeFilename(filename string) string

SafeFilename maps an attachment's original filename onto the final path segment of its archive entry. The mapping is deterministic so that a re-export of the same attachment lands at the same entry name.

func ValidateEntryName

func ValidateEntryName(name string) error

ValidateEntryName applies the container rules to a ZIP entry name or a record path member. It never repairs a name: a violation is an error so that an unsafe archive is rejected whole.

func ValidateUID

func ValidateUID(uid string) error

ValidateUID checks the public resource UID grammar shared by memos, attachments, and Spaces.

Types

type Attachment

type Attachment struct {
	UID          string `json:"uid"`
	Filename     string `json:"filename"`
	Type         string `json:"type"`
	Size         int64  `json:"size"`
	SHA256       string `json:"sha256,omitempty"`
	Path         string `json:"path,omitempty"`
	ExternalLink string `json:"externalLink,omitempty"`
	CreateTime   string `json:"createTime"`
	// MediaMetadata is the public API MediaMetadata message in its proto3
	// JSON mapping. It is carried verbatim so this package needs no proto
	// dependency.
	MediaMetadata json.RawMessage `json:"mediaMetadata,omitempty"`
}

Attachment is one entry of a memo record's attachments list.

type Counts

type Counts struct {
	Memos       int `json:"memos"`
	Attachments int `json:"attachments"`
}

Counts lets readers detect truncation and report progress.

type File

type File struct {
	Manifest *Manifest
	Memos    []*Memo
	// Warnings lists every soft deviation the reader corrected.
	Warnings []Warning
	// contains filtered or unexported fields
}

File is a validated, opened Memos export file. Memos are ordered so that a parent precedes its comments, then by createTime, then by UID.

func Read

func Read(r io.ReaderAt, size int64) (*File, error)

Read validates the container and loads every memo record. It fails on the first hard violation without returning a partial archive.

func (*File) Content

func (a *File) Content(memo *Memo) ([]byte, error)

Content returns the exact bytes of a memo's content file.

func (*File) ReadAttachment

func (a *File) ReadAttachment(attachment *Attachment) ([]byte, error)

ReadAttachment returns the bytes of an attachment entry after checking their length and SHA-256 digest against the attachment record.

type Generator

type Generator struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

Generator names the software that wrote the archive.

type Location

type Location struct {
	Placeholder string  `json:"placeholder,omitempty"`
	Latitude    float64 `json:"latitude"`
	Longitude   float64 `json:"longitude"`
}

Location mirrors the public API Location message.

type Manifest

type Manifest struct {
	Format        string    `json:"format"`
	FormatVersion string    `json:"formatVersion"`
	Generator     Generator `json:"generator"`
	ExportTime    string    `json:"exportTime"`
	Scope         Scope     `json:"scope"`
	Counts        *Counts   `json:"counts,omitempty"`
}

Manifest is the archive-level record stored at manifest.json.

type Memo

type Memo struct {
	UID         string       `json:"uid"`
	Creator     string       `json:"creator"`
	CreateTime  string       `json:"createTime"`
	UpdateTime  string       `json:"updateTime"`
	State       string       `json:"state"`
	Visibility  string       `json:"visibility"`
	Pinned      bool         `json:"pinned"`
	ContentPath string       `json:"contentPath"`
	Tags        []string     `json:"tags,omitempty"`
	Location    *Location    `json:"location,omitempty"`
	Space       *Space       `json:"space,omitempty"`
	Parent      string       `json:"parent,omitempty"`
	Relations   []Relation   `json:"relations,omitempty"`
	Attachments []Attachment `json:"attachments,omitempty"`
	Reactions   []Reaction   `json:"reactions,omitempty"`
}

Memo is the record stored at memos/<uid>.json.

type Reaction

type Reaction struct {
	ReactionType string `json:"reactionType"`
	Creator      string `json:"creator"`
	CreateTime   string `json:"createTime,omitempty"`
}

Reaction mirrors the public API Reaction message with a username creator.

type Relation

type Relation struct {
	Type string `json:"type"`
	Memo string `json:"memo"`
}

Relation is an outgoing REFERENCE relation.

type Scope

type Scope struct {
	Kind string     `json:"kind"`
	User *ScopeUser `json:"user,omitempty"`
}

Scope says whose memos the archive holds.

type ScopeUser

type ScopeUser struct {
	Username    string `json:"username"`
	DisplayName string `json:"displayName,omitempty"`
}

ScopeUser identifies the exporting user.

type Space

type Space struct {
	UID   string `json:"uid"`
	Title string `json:"title,omitempty"`
}

Space names the Space a memo was placed in.

type Warning

type Warning struct {
	UID     string
	Message string
}

Warning records a recoverable deviation found while reading a record. The reader applies the documented fallback and continues.

func (Warning) String

func (w Warning) String() string

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer streams a Memos export file to an io.Writer. Entries are written in the order the caller supplies them, so a caller that wants attachment digests in a memo record writes the attachment bytes before the record.

func NewWriter

func NewWriter(w io.Writer, modified time.Time) *Writer

NewWriter starts an archive on w. Every entry is stamped with modified, normally the export time; the zero time means now. A real timestamp matters because some extractors refuse the all-zero MS-DOS date that an unset time produces.

func (*Writer) Close

func (w *Writer) Close() error

Close finishes the central directory. The archive is unusable until Close returns nil.

func (*Writer) WriteAttachment

func (w *Writer) WriteAttachment(path string, content io.Reader) (string, int64, error)

WriteAttachment copies attachment bytes into the entry at path and returns the digest and length it observed, which the caller records on the attachment entry.

func (*Writer) WriteManifest

func (w *Writer) WriteManifest(manifest *Manifest) error

WriteManifest writes manifest.json. It fills in the format name and version, and must be called exactly once.

func (*Writer) WriteMemo

func (w *Writer) WriteMemo(memo *Memo, content []byte) error

WriteMemo writes a memo record and its content file. The record's contentPath is set to the conventional location. Attachment entries that carry a path must already have been written with WriteAttachment.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL