Commit Diff


commit - c8d63abe544d1425ee432f5c96ec28f9254e7de0
commit + e48f0422427ae70cc25ac8b2c39a671eca141898
blob - f3ab816fca856ca32427ba87310a265f045fb83d
blob + 6d2879c6eeac9346f577d13ae7e63840f80280d8
--- client.go
+++ client.go
@@ -135,9 +135,9 @@ func (c *Client) Posts(community string, mode ListMode
 
 	params := map[string]string{
 		"community_name": community,
-		"limit":          "30",
-		"type_":          string(mode),
-		"sort":           "New",
+		//		"limit":          "30",
+		"type_": string(mode),
+		"sort":  "New",
 	}
 	resp, err := c.get("post/list", params)
 	if err != nil {
blob - 737cdeff0457724aa4257ced480808449601ece2
blob + 605b1a4b77e149252b6236d64f044a0630fc3255
--- fs/file.go
+++ fs/file.go
@@ -75,21 +75,21 @@ func (f *dummy) ReadDir(n int) ([]fs.DirEntry, error) 
 	return f.dirinfo.ReadDir(n)
 }
 
-type comFile struct {
-	name    string
+type lFile struct {
+	info    fs.FileInfo
 	dirinfo *dirInfo
 	client  *lemmy.Client
 	buf     io.ReadCloser
 }
 
-func (f *comFile) Read(p []byte) (int, error) {
+func (f *lFile) Read(p []byte) (int, error) {
 	if f.buf == nil {
 		f.buf = io.NopCloser(strings.NewReader("directory"))
 	}
 	return f.buf.Read(p)
 }
 
-func (f *comFile) Close() error {
+func (f *lFile) Close() error {
 	if f.buf == nil || f.dirinfo == nil {
 		return fs.ErrClosed
 	}
@@ -99,36 +99,40 @@ func (f *comFile) Close() error {
 	return err
 }
 
-func (f *comFile) Stat() (fs.FileInfo, error) {
-	community, _, err := f.client.LookupCommunity(f.name)
-	if err != nil {
-		return nil, &fs.PathError{"stat", f.name, err}
-	}
-	return &community, nil
+func (f *lFile) Stat() (fs.FileInfo, error) {
+	return f.info, nil
 }
 
-func (f *comFile) ReadDir(n int) ([]fs.DirEntry, error) {
+func (f *lFile) ReadDir(n int) ([]fs.DirEntry, error) {
 	if f.dirinfo == nil {
 		f.dirinfo = new(dirInfo)
-		posts, err := f.client.Posts(f.name, lemmy.ListAll)
-		if err != nil {
-			return nil, &fs.PathError{"readdir", f.name, err}
-		}
-		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)
+		switch f.info.(type) {
+		case *lemmy.Community:
+			posts, err := f.client.Posts(f.info.Name(), lemmy.ListAll)
 			if err != nil {
-				return nil, &fs.PathError{"readdir", f.name, err}
+				return nil, &fs.PathError{"readdir", f.info.Name(), err}
 			}
-			for i := range comments {
-				f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&comments[i]))
+			for _, p := range posts {
+				p := p
+				f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&p))
 			}
+		case *lemmy.Post:
+			p := f.info.(*lemmy.Post)
+			comments, err := f.client.Comments(p.ID, lemmy.ListAll)
+			if err != nil {
+				return nil, &fs.PathError{"readdir", f.info.Name(), err}
+			}
+			for _, c := range comments {
+				c := c
+				f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&c))
+			}
+		default:
+			return nil, &fs.PathError{"readdir", f.info.Name(), fmt.Errorf("not a directory")}
 		}
 	}
 	return f.dirinfo.ReadDir(n)
 }
-func postFile(p *lemmy.Post) *dummy {
+func postText(p *lemmy.Post) *bytes.Buffer {
 	buf := &bytes.Buffer{}
 	fmt.Fprintln(buf, "From:", p.CreatorID)
 	fmt.Fprintf(buf, "Message-Id: <%d>\n", p.ID)
@@ -140,15 +144,10 @@ func postFile(p *lemmy.Post) *dummy {
 		fmt.Fprintln(buf, p.URL)
 	}
 	fmt.Fprintln(buf, p.Body)
-	return &dummy{
-		name:  p.Name(),
-		mode:  p.Mode(),
-		mtime: p.ModTime(),
-		buf:   io.NopCloser(buf),
-	}
+	return buf
 }
 
-func commentFile(c *lemmy.Comment) *dummy {
+func commentText(c *lemmy.Comment) *bytes.Buffer {
 	buf := &bytes.Buffer{}
 	fmt.Fprintln(buf, "From:", c.CreatorID)
 	fmt.Fprintln(buf, "Date:", c.ModTime().Format(time.RFC822))
@@ -157,10 +156,5 @@ func commentFile(c *lemmy.Comment) *dummy {
 	fmt.Fprintln(buf, "Subject: Re:", c.PostID)
 	fmt.Fprintln(buf)
 	fmt.Fprintln(buf, c.Content)
-	return &dummy{
-		name:  c.Name(),
-		mode:  c.Mode(),
-		mtime: c.ModTime(),
-		buf:   io.NopCloser(buf),
-	}
+	return buf
 }
blob - 6d1f3609b1b649e5af5e55d0971bae105b3cfaf3
blob + 77cd53b4dd55e445d66dfc46f9e648ebb44357da
--- fs/fs.go
+++ fs/fs.go
@@ -67,7 +67,7 @@ func (fsys *FS) Open(name string) (fs.File, error) {
 	elems := strings.Split(name, "/")
 	// We've only got communities, then posts/comments.
 	// Anything deeper cannot exist.
-	if len(elems) >= 3 {
+	if len(elems) > 3 {
 		return nil, &fs.PathError{"open", name, fs.ErrNotExist}
 	}
 
@@ -83,8 +83,8 @@ func (fsys *FS) Open(name string) (fs.File, error) {
 		fsys.Communities[elems[0]] = community
 	}
 	if len(elems) == 1 {
-		return &comFile{
-			name:   community.Name(),
+		return &lFile{
+			info:   &community,
 			buf:    io.NopCloser(strings.NewReader(community.Name())),
 			client: fsys.Client,
 		}, nil
@@ -92,23 +92,37 @@ 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/comment id")}
+		return nil, &fs.PathError{"open", name, fmt.Errorf("bad post id")}
 	}
-
-	comment, err := fsys.Client.LookupComment(id)
-	if err == nil {
-		return commentFile(&comment), nil
-	} else if !errors.Is(err, lemmy.ErrNotFound) {
+	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}
 	}
+	if len(elems) == 2 {
+		return &lFile{
+			info:   &post,
+			buf:    io.NopCloser(strings.NewReader(post.Name())),
+			client: fsys.Client,
+		}, nil
+	}
 
-	post, err := fsys.Client.LookupPost(comment.PostID)
+	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)
 	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 postFile(&post), nil
+	return &lFile{
+		info:   &comment,
+		buf:    io.NopCloser(commentText(&comment)),
+		client: fsys.Client,
+	}, nil
 }
 
 func (fsys *FS) openRoot() (fs.File, error) {
blob - 5a2535c9b22ecc0063639e072d0752be579754a9
blob + 334017bb586e4f41c0446025d447371b743c024e
--- fs/fs_test.go
+++ fs/fs_test.go
@@ -1,6 +1,7 @@
 package fs
 
 import (
+	"io/fs"
 	"net/http"
 	"testing"
 	"testing/fstest"
@@ -23,8 +24,12 @@ func TestFS(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
+	_, err = fs.ReadFile(fsys, "zzztestcommunity1/447/331")
+	if err != nil {
+		t.Fatal(err)
+	}
 
-	if err := fstest.TestFS(fsys, "zzztestcommunity1", "zzztestcommunity1/447/title", "zzztestcommunity1/447/331"); err != nil {
+	if err := fstest.TestFS(fsys, "zzztestcommunity1", "zzztestcommunity1/447/post", "zzztestcommunity1/447/331"); err != nil {
 		t.Fatal(err)
 	}
 }
blob - bfd8c68f667c8b63dc9833c24659b00d7a55acba
blob + 5cd7fe34aff26c2b4021d73e29266fc0377733e7
--- lemmy.go
+++ lemmy.go
@@ -22,7 +22,7 @@ func (c *Community) Name() string       { return c.Str
 func (c *Community) Size() int64        { return 0 }
 func (c *Community) Mode() fs.FileMode  { return fs.ModeDir | 0o0555 }
 func (c *Community) ModTime() time.Time { return c.Published }
-func (c *Community) IsDir() bool        { return true }
+func (c *Community) IsDir() bool        { return c.Mode().IsDir() }
 func (c *Community) Sys() interface{}   { return nil }
 
 func (c Community) String() string {
@@ -51,9 +51,9 @@ func (p *Post) Size() int64 {
 	return int64(len(p.Body))
 }
 
-func (p *Post) Mode() fs.FileMode  { return fs.ModeDir | 0o0444 }
+func (p *Post) Mode() fs.FileMode  { return fs.ModeDir | 0o0555 }
 func (p *Post) ModTime() time.Time { return p.Published }
-func (p *Post) IsDir() bool        { return true }
+func (p *Post) IsDir() bool        { return p.Mode().IsDir() }
 func (p *Post) Sys() interface{}   { return nil }
 
 type Comment struct {