Commit Diff


commit - d4b74d7a68368284eca18e00ef626542ae8bb20c
commit + a439d275a8384994f6408e51de38553275fba918
blob - 0e77af598acb419e017ac16d27b15bf86ec8c861
blob + 3501d481db3d7c8fc4ae0c37bf21e1787f61ba69
--- fs/file.go
+++ fs/file.go
@@ -2,11 +2,9 @@ package fs
 
 import (
 	"bytes"
-	"errors"
 	"fmt"
 	"io"
 	"io/fs"
-	"strconv"
 	"strings"
 	"time"
 
@@ -116,99 +114,55 @@ func (f *comFile) ReadDir(n int) ([]fs.DirEntry, error
 		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
@@ -60,12 +60,16 @@ func (fsys *FS) Open(name string) (fs.File, error) {
 			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 {
@@ -88,54 +92,23 @@ func (fsys *FS) Open(name string) (fs.File, error) {
 
 	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) {