21 func (fsys *FS) start() error {
22 if fsys.Client == nil {
23 fsys.Client = &lemmy.Client{}
29 func (fsys *FS) Open(name string) (fs.File, error) {
30 if !fs.ValidPath(name) {
31 return nil, &fs.PathError{"open", name, fs.ErrInvalid}
32 } else if strings.Contains(name, `\`) {
33 return nil, &fs.PathError{"open", name, fs.ErrInvalid}
35 name = path.Clean(name)
38 if err := fsys.start(); err != nil {
39 return nil, fmt.Errorf("start fs: %w", err)
43 return fsys.openRoot()
46 elems := strings.Split(name, "/")
47 // We've only got communities, then posts/comments.
48 // Anything deeper cannot exist.
50 return nil, &fs.PathError{"open", name, fs.ErrNotExist}
53 community, _, err := fsys.Client.LookupCommunity(elems[0])
54 if errors.Is(err, lemmy.ErrNotFound) {
55 return nil, &fs.PathError{"open", name, fs.ErrNotExist}
56 } else if err != nil {
57 return nil, &fs.PathError{"open", name, err}
62 buf: io.NopCloser(strings.NewReader(community.Name())),
67 id, err := strconv.Atoi(elems[1])
69 return nil, &fs.PathError{"open", name, fmt.Errorf("bad post id")}
71 post, err := fsys.Client.LookupPost(id)
72 if errors.Is(err, lemmy.ErrNotFound) {
73 return nil, &fs.PathError{"open", name, fs.ErrNotExist}
74 } else if err != nil {
75 return nil, &fs.PathError{"open", name, err}
80 buf: io.NopCloser(strings.NewReader(post.Name())),
84 if elems[2] == "post" {
85 info, err := postFile(&post).Stat()
87 return nil, &fs.PathError{"open", name, fmt.Errorf("prepare post file info: %w", err)}
91 buf: io.NopCloser(postText(&post)),
96 id, err = strconv.Atoi(elems[2])
98 return nil, &fs.PathError{"open", name, fmt.Errorf("bad comment id")}
100 comment, err := fsys.Client.LookupComment(id)
101 if errors.Is(err, lemmy.ErrNotFound) {
102 return nil, &fs.PathError{"open", name, fs.ErrNotExist}
103 } else if err != nil {
104 return nil, &fs.PathError{"open", name, err}
108 buf: io.NopCloser(commentText(&comment)),
113 func (fsys *FS) openRoot() (fs.File, error) {
114 dirinfo := new(dirInfo)
115 communities, err := fsys.Client.Communities(lemmy.ListAll)
119 for _, c := range communities {
121 dent := fs.FileInfoToDirEntry(&c)
122 dirinfo.entries = append(dirinfo.entries, dent)
126 mode: fs.ModeDir | 0444,
127 contents: []byte("hello, world!"),