commit - d4b74d7a68368284eca18e00ef626542ae8bb20c
commit + a439d275a8384994f6408e51de38553275fba918
blob - 0e77af598acb419e017ac16d27b15bf86ec8c861
blob + 3501d481db3d7c8fc4ae0c37bf21e1787f61ba69
--- fs/file.go
+++ fs/file.go
import (
"bytes"
- "errors"
"fmt"
"io"
"io/fs"
- "strconv"
"strings"
"time"
if err != nil {
return nil, &fs.PathError{"readdir", f.name, err}
}
- for i := range posts {
- f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&posts[i]))
+ for _, post := range posts {
+ post := post
+ f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&post))
+ comments, err := f.client.Comments(post.ID, lemmy.ListAll)
+ if err != nil {
+ return nil, &fs.PathError{"readdir", f.name, err}
+ }
+ for i := range comments {
+ f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&comments[i]))
+ }
}
}
return f.dirinfo.ReadDir(n)
}
-
-type postFile struct {
- post lemmy.Post
- dirinfo *dirInfo
- client *lemmy.Client
- buf io.ReadCloser
-}
-
-func (f *postFile) Stat() (fs.FileInfo, error) {
- name := strconv.Itoa(f.post.ID)
- var err error
- f.post, err = f.client.LookupPost(f.post.ID)
- if errors.Is(err, lemmy.ErrNotFound) {
- return nil, &fs.PathError{"stat", name, fs.ErrNotExist}
- } else if err != nil {
- return nil, &fs.PathError{"stat", name, err}
+func postFile(p *lemmy.Post) *dummy {
+ buf := &bytes.Buffer{}
+ fmt.Fprintln(buf, "From:", p.CreatorID)
+ fmt.Fprintf(buf, "Message-Id: <%d>\n", p.ID)
+ fmt.Fprintf(buf, "List-Archive: <%s>\n", p.ActivityURL)
+ fmt.Fprintln(buf, "Date:", p.ModTime().Format(time.RFC822))
+ fmt.Fprintln(buf, "Subject:", p.Title)
+ fmt.Fprintln(buf)
+ if p.URL != "" {
+ fmt.Fprintln(buf, p.URL)
}
- return &f.post, nil
-}
-
-func (f *postFile) Read(p []byte) (int, error) {
- if f.buf == nil {
- return 0, io.EOF
+ fmt.Fprintln(buf, p.Body)
+ return &dummy{
+ name: p.Name(),
+ mode: p.Mode(),
+ mtime: p.ModTime(),
+ buf: io.NopCloser(buf),
}
- return f.buf.Read(p)
}
-func (f *postFile) Close() error {
- if f.buf == nil || f.dirinfo == nil {
- return fs.ErrClosed
- }
- f.dirinfo = nil
- err := f.buf.Close()
- f.buf = nil
- return err
-}
+func commentFile(c *lemmy.Comment, person lemmy.Person, post lemmy.Post) *dummy {
+ buf := &bytes.Buffer{}
+ fmt.Fprintln(buf, "From:", person.String())
+ fmt.Fprintln(buf, "Date:", c.ModTime().Format(time.RFC822))
+ fmt.Fprintf(buf, "Message-Id: <%d>\n", c.ID)
+ fmt.Fprintf(buf, "List-Archive: <%s>\n", c.ActivityURL)
+ fmt.Fprintln(buf, "Subject: Re:", post.Title)
-func (f *postFile) ReadDir(n int) ([]fs.DirEntry, error) {
- name := strconv.Itoa(f.post.ID)
- if f.dirinfo == nil {
- f.dirinfo = new(dirInfo)
- for _, v := range postFiles(f.post) {
- f.dirinfo.entries = append(f.dirinfo.entries, v)
- }
- comments, err := f.client.Comments(f.post.ID, lemmy.ListAll)
- if err != nil {
- return nil, &fs.PathError{"readdir", name, err}
- }
- for i := range comments {
- f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&comments[i]))
- }
+ refs, err := c.References()
+ if err != nil || len(refs) <= 2 {
+ fmt.Fprintf(buf, "References: <%d>\n", c.PostID)
+ } else {
+ fmt.Fprintf(buf, "References: <%d>\n", refs[len(refs)-2])
}
- return f.dirinfo.ReadDir(n)
-}
-func postFiles(post lemmy.Post) map[string]*dummy {
- m := make(map[string]*dummy)
- m["body"] = &dummy{
- name: "body",
- mode: 0444,
- contents: []byte(post.Body),
- mtime: post.ModTime(),
- }
- m["creator"] = &dummy{
- name: "creator",
- mode: 0444,
- contents: []byte(strconv.Itoa(post.CreatorID)),
- mtime: post.ModTime(),
- }
- m["title"] = &dummy{
- name: "title",
- mode: 0444,
- contents: []byte(post.Title),
- mtime: post.ModTime(),
- }
- m["url"] = &dummy{
- name: "url",
- mode: 0444,
- contents: []byte(post.URL),
- mtime: post.ModTime(),
- }
- return m
-}
-
-func commentFile(c *lemmy.Comment) *dummy {
- buf := &bytes.Buffer{}
- fmt.Fprintf(buf, "From: %d\n", c.CreatorID)
fmt.Fprintln(buf)
fmt.Fprintln(buf, c.Content)
return &dummy{
blob - 798eb37e257ab1e4e90922d31f86ab832ec5688f
blob + 0c8f335984284995fb3d46ebb73e9eb9a761bdd9
--- fs/fs.go
+++ fs/fs.go
return nil, fmt.Errorf("start fs: %w", err)
}
}
-
if name == "." {
return fsys.openRoot()
}
elems := strings.Split(name, "/")
+ // We've only got communities, then posts/comments.
+ // Anything deeper cannot exist.
+ if len(elems) >= 3 {
+ return nil, &fs.PathError{"open", name, fs.ErrNotExist}
+ }
community, ok := fsys.Communities[elems[0]]
if !ok {
id, err := strconv.Atoi(elems[1])
if err != nil {
- return nil, &fs.PathError{"open", name, fmt.Errorf("bad post id")}
+ return nil, &fs.PathError{"open", name, fmt.Errorf("bad post/comment id")}
}
- post, ok := fsys.Posts[id]
- if !ok || len(elems) == 2 {
- post, err = fsys.Client.LookupPost(id)
- if errors.Is(err, lemmy.ErrNotFound) {
- delete(fsys.Posts, id)
- return nil, &fs.PathError{"open", name, fs.ErrNotExist}
- } else if err != nil {
- return nil, &fs.PathError{"open", name, err}
- }
- fsys.Posts[id] = post
- }
- if len(elems) == 2 {
- return &postFile{
- post: post,
- buf: io.NopCloser(strings.NewReader("")),
- client: fsys.Client,
- }, nil
+ comment, creator, post, err := fsys.Client.LookupComment(id)
+ if err == nil {
+ return commentFile(&comment, creator, post), nil
+ } else if !errors.Is(err, lemmy.ErrNotFound) {
+ return nil, &fs.PathError{"open", name, err}
}
- // At the bottom of the tree. If there's more than one element left then
- // it cannot exist.
- if len(elems) > 3 {
- return nil, &fs.PathError{"open", name, fs.ErrNotExist}
- }
-
- // if it's not a numbered directory (comment) it must be a regular file.
- if !strings.ContainsAny(elems[2], "0123456789") {
- files := postFiles(post)
- if f, ok := files[elems[2]]; ok {
- return f, nil
- }
- return nil, &fs.PathError{"open", name, fs.ErrNotExist}
- }
-
- id, err = strconv.Atoi(elems[2])
- if err != nil {
- return nil, &fs.PathError{"open", name, fmt.Errorf("bad comment id")}
- }
- comment, err := fsys.Client.LookupComment(id)
+ post, err = fsys.Client.LookupPost(id)
if errors.Is(err, lemmy.ErrNotFound) {
return nil, &fs.PathError{"open", name, fs.ErrNotExist}
} else if err != nil {
return nil, &fs.PathError{"open", name, err}
}
- return commentFile(&comment), nil
+ return postFile(&post), nil
}
func (fsys *FS) openRoot() (fs.File, error) {