Documentation
¶
Overview ¶
Package repo is the on-disk tori repository: the path-mapping rules, the record store, the manifest, and the incremental merge. layout.go is the pure heart of it — every file in a repository is a deterministic function of the record it holds, with no network and no clock, so the layout is testable in isolation and a re-capture lands on the exact same paths (spec §6).
Index ¶
- Constants
- func AvatarPath(handle, srcURL, ext string) string
- func BannerPath(handle, ext string) string
- func MediaPath(typ, key, srcURL, ext string) string
- func MediaSubdir(typ string) string
- func Rel(from, to string) string
- func ThreadHTML(root string) string
- func ThreadMD(root string) string
- func TweetHTML(id string) string
- func TweetJSON(id string) string
- func TweetMD(id string) string
- func TweetRaw(id string) string
- type Asset
- type Capture
- type Manifest
- type Range
- type Store
- func (s *Store) Exists(rel string) bool
- func (s *Store) HasTweet(id string) bool
- func (s *Store) LoadProfile() (*x.User, bool, error)
- func (s *Store) LoadTweet(id string) (*x.Tweet, error)
- func (s *Store) LoadTweets() ([]*x.Tweet, error)
- func (s *Store) WriteMedia(rel string, b []byte) error
- func (s *Store) WriteProfile(u *x.User) error
- func (s *Store) WriteText(rel, body string) error
- func (s *Store) WriteTweet(t *x.Tweet, raw json.RawMessage) error
- type TargetRef
Constants ¶
const ( ManifestFile = "manifest.json" StateFile = "state.json" ProfileFile = "profile.json" IndexFile = "index.html" ReadmeFile = "README.md" AssetsDir = "_assets" CSSFile = "_assets/tori.css" )
Well-known files at the repository root.
const ( TweetsDir = "tweets" ThreadsDir = "threads" HTMLDir = "html" MDDir = "md" MediaDir = "media" )
Sub-directories that hold the per-record files.
const SchemaVersion = 1
SchemaVersion is the on-disk manifest layout version, bumped when the repo shape changes so a future tori can migrate an old archive (spec §6.5).
Variables ¶
This section is empty.
Functions ¶
func AvatarPath ¶
AvatarPath maps a profile avatar to a stable local file keyed by handle and the size segment X embeds in its URL (e.g. _400x400).
func BannerPath ¶
BannerPath maps a profile banner to a stable local file keyed by handle.
func MediaPath ¶
MediaPath maps a media item to its deterministic local file (spec §6.3). The stem is the media key plus the first 6 hex of a sha256 of the source URL, so two renditions of one key never collide and a photo referenced by a thousand tweets resolves to one file. The extension comes from ext (derived from the URL or the Content-Type by the caller).
func MediaSubdir ¶
MediaSubdir is the directory a media type lives under within media/. X serves animated GIFs as mp4, so they get their own bucket distinct from real video.
func Rel ¶
Rel returns the relative path from the directory holding the page at from to the file at to, both repository-relative with forward slashes (spec §6.4). It is what rewrites a media src or a cross-tweet link inside a rendered page so the archive resolves with the network unplugged. It never escapes the repo root because both inputs are already repo-relative.
func ThreadHTML ¶
ThreadHTML is a reconstructed conversation rendered as one inert page.
func TweetJSON ¶
TweetJSON is the canonical record path for a tweet id (spec §6.2). The id is a snowflake string used verbatim, so the path is a pure function of the id and a re-capture overwrites the same file.
Types ¶
type Asset ¶
type Asset struct {
Key string `json:"key"`
Type string `json:"type"`
Path string `json:"path,omitempty"` // repo-relative local path, empty if not on disk
Source string `json:"source,omitempty"` // original URL
Status string `json:"status"` // local | unavailable | stream-only | skipped
}
Asset records where one media item went on disk, so the repository is honest about exactly what is and is not localised (spec §8).
type Capture ¶
Capture records one archive run: when it happened (the --date stamp), how many records it added, and which tier served them. This is the only place a wall-clock value lives in the manifest (TP5).
type Manifest ¶
type Manifest struct {
Service string `json:"service"`
Target TargetRef `json:"target"`
TiersUsed []string `json:"tiers_used"`
Tweets int `json:"tweets"`
Media int `json:"media"`
Threads int `json:"threads"`
Range Range `json:"range"`
Captures []Capture `json:"captures"`
MediaIndex []Asset `json:"media_index,omitempty"`
ToriVersion string `json:"tori_version"`
Schema int `json:"schema"`
}
Manifest is the repository index — the first file tori info, tori add, and tori render read. Its record-bearing fields are sorted deterministically so a re-capture of the same bytes writes a byte-identical manifest (TP5); the only wall-clock values live in Captures and are passed in at the surface boundary.
func LoadManifest ¶
LoadManifest reads manifest.json from a repository root, returning ok=false when the repo does not yet exist.
func NewManifest ¶
NewManifest builds an empty manifest for a target.
func (*Manifest) AddCapture ¶
AddCapture appends one capture entry.
type Range ¶
type Range struct {
Oldest time.Time `json:"oldest,omitempty"`
Newest time.Time `json:"newest,omitempty"`
}
Range is the oldest/newest captured tweet timestamp.
type Store ¶
type Store struct {
Root string
}
Store is a handle on one repository directory. It writes and reads the canonical records, the raw payloads, and the media files; it owns no network and no policy beyond the layout rules in layout.go.
func (*Store) LoadProfile ¶
LoadProfile reads profile.json, returning ok=false when absent.
func (*Store) LoadTweets ¶
LoadTweets reads every canonical record under tweets/, sorted by id ascending so callers (render, merge, manifest) get a deterministic order (TP5).
func (*Store) WriteMedia ¶
WriteMedia writes localised media bytes to a repo-relative path.
func (*Store) WriteProfile ¶
WriteProfile persists the captured User as profile.json.
func (*Store) WriteText ¶
WriteText writes an arbitrary repo-relative text file (a rendered page, the CSS, an index).
func (*Store) WriteTweet ¶
WriteTweet persists the canonical record and, when present, the untouched upstream payload beside it (TP3). The canonical JSON is indented and sorted by field for a stable, diff-friendly file.