repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

pico / pkg / apps / feeds
Antonio Mika  ·  2025-03-12

scp_hooks.go

 1package feeds
 2
 3import (
 4	"errors"
 5	"fmt"
 6	"net/url"
 7
 8	"strings"
 9	"time"
10
11	"github.com/picosh/pico/pkg/db"
12	"github.com/picosh/pico/pkg/filehandlers"
13	"github.com/picosh/pico/pkg/pssh"
14	"github.com/picosh/pico/pkg/shared"
15	"github.com/picosh/utils"
16)
17
18type FeedHooks struct {
19	Cfg *shared.ConfigSite
20	Db  db.DB
21}
22
23func (p *FeedHooks) FileValidate(s *pssh.SSHServerConnSession, data *filehandlers.PostMetaData) (bool, error) {
24	if !utils.IsTextFile(string(data.Text)) {
25		err := fmt.Errorf(
26			"WARNING: (%s) invalid file must be plain text (utf-8), skipping",
27			data.Filename,
28		)
29		return false, err
30	}
31
32	if !utils.IsExtAllowed(data.Filename, p.Cfg.AllowedExt) {
33		extStr := strings.Join(p.Cfg.AllowedExt, ",")
34		err := fmt.Errorf(
35			"WARNING: (%s) invalid file, format must be (%s), skipping",
36			data.Filename,
37			extStr,
38		)
39		return false, err
40	}
41
42	// Because we need to support sshfs, sftp runs our Write handler twice
43	// and on the first pass we do not have access to the file data.
44	// In that case we should skip the parsing validation
45	if data.Text == "" {
46		return true, nil
47	}
48
49	parsed := shared.ListParseText(string(data.Text))
50	if parsed.Email == "" {
51		return false, fmt.Errorf("ERROR: no email variable detected for %s, check the format of your file, skipping", data.Filename)
52	}
53
54	var allErr error
55	for _, txt := range parsed.Items {
56		u := ""
57		if txt.IsText {
58			u = txt.Value
59		} else if txt.IsURL {
60			u = string(txt.URL)
61		}
62
63		_, err := url.Parse(u)
64		if err != nil {
65			allErr = errors.Join(allErr, fmt.Errorf("%s: %w", u, err))
66			continue
67		}
68	}
69	if allErr != nil {
70		return false, fmt.Errorf("ERROR: some urls provided were invalid check the format of your file, skipping: %w", allErr)
71	}
72
73	return true, nil
74}
75
76func (p *FeedHooks) FileMeta(s *pssh.SSHServerConnSession, data *filehandlers.PostMetaData) error {
77	if data.Data.LastDigest == nil {
78		now := time.Now()
79		// let it run on the next loop
80		dd := now.AddDate(0, 0, -31)
81		data.Data.LastDigest = &dd
82	}
83
84	return nil
85}