14 type fakeStat struct {
21 func (s *fakeStat) Name() string { return s.name }
22 func (s *fakeStat) Size() int64 { return s.size }
23 func (s *fakeStat) Mode() fs.FileMode { return s.mode }
24 func (s *fakeStat) ModTime() time.Time { return s.mtime }
25 func (s *fakeStat) IsDir() bool { return s.mode.IsDir() }
26 func (s *fakeStat) Sys() any { return nil }
37 func (f *dummy) Name() string { return f.name }
38 func (f *dummy) IsDir() bool { return f.mode.IsDir() }
39 func (f *dummy) Type() fs.FileMode { return f.mode.Type() }
40 func (f *dummy) Info() (fs.FileInfo, error) { return f.Stat() }
42 func (f *dummy) Stat() (fs.FileInfo, error) {
46 size: int64(len(f.contents)),
51 func (f *dummy) Read(p []byte) (int, error) {
53 f.buf = io.NopCloser(bytes.NewReader(f.contents))
58 func (f *dummy) Close() error {
67 func (f *dummy) ReadDir(n int) ([]fs.DirEntry, error) {
69 return nil, &fs.PathError{"readdir", f.name, fmt.Errorf("not a directory")}
70 } else if f.dirinfo == nil {
71 // TODO(otl): is this accidental? maybe return an error here.
72 return nil, &fs.PathError{"readdir", f.name, fmt.Errorf("no dirinfo to track reads")}
75 return f.dirinfo.ReadDir(n)
85 func (f *lFile) Read(p []byte) (int, error) {
87 f.buf = io.NopCloser(strings.NewReader("directory"))
92 func (f *lFile) Close() error {
93 if f.buf == nil || f.dirinfo == nil {
102 func (f *lFile) Stat() (fs.FileInfo, error) {
106 func (f *lFile) ReadDir(n int) ([]fs.DirEntry, error) {
107 if f.dirinfo == nil {
108 f.dirinfo = new(dirInfo)
109 switch f.info.(type) {
110 case *lemmy.Community:
111 posts, err := f.client.Posts(f.info.Name(), lemmy.ListAll)
113 return nil, &fs.PathError{"readdir", f.info.Name(), err}
115 for _, p := range posts {
117 f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&p))
120 p := f.info.(*lemmy.Post)
121 comments, err := f.client.Comments(p.ID, lemmy.ListAll)
123 return nil, &fs.PathError{"readdir", f.info.Name(), err}
125 for _, c := range comments {
127 f.dirinfo.entries = append(f.dirinfo.entries, fs.FileInfoToDirEntry(&c))
129 f.dirinfo.entries = append(f.dirinfo.entries, postFile(p))
131 return nil, &fs.PathError{"readdir", f.info.Name(), fmt.Errorf("not a directory")}
134 return f.dirinfo.ReadDir(n)
136 func postText(p *lemmy.Post) *bytes.Buffer {
137 buf := &bytes.Buffer{}
138 fmt.Fprintln(buf, "From:", p.CreatorID)
139 fmt.Fprintf(buf, "Message-Id: <%d>\n", p.ID)
140 fmt.Fprintf(buf, "List-Archive: <%s>\n", p.URL)
141 fmt.Fprintln(buf, "Date:", p.ModTime().Format(time.RFC822))
142 fmt.Fprintln(buf, "Subject:", p.Title)
145 fmt.Fprintln(buf, p.URL)
147 fmt.Fprintln(buf, p.Body)
151 func postFile(p *lemmy.Post) *dummy {
156 contents: postText(p).Bytes(),
160 func commentText(c *lemmy.Comment) *bytes.Buffer {
161 buf := &bytes.Buffer{}
162 fmt.Fprintln(buf, "From:", c.CreatorID)
163 fmt.Fprintln(buf, "Date:", c.ModTime().Format(time.RFC822))
164 fmt.Fprintf(buf, "Message-ID: <%d>\n", c.ID)
165 fmt.Fprintf(buf, "List-Archive: <%s>\n", c.ActivityURL)
166 fmt.Fprintln(buf, "Subject: Re:", c.PostID)
168 fmt.Fprintln(buf, c.Content)