Subscribe and post RSS feeds to Bluesky
rss bluesky
at main 1.7 kB view raw
1package storage 2 3import ( 4 "bufio" 5 "fmt" 6 "os" 7 "sync" 8) 9 10// Storage handles persistence of posted item GUIDs 11type Storage struct { 12 filePath string 13 posted map[string]bool 14 mu sync.RWMutex 15} 16 17// New creates a new storage instance 18func New(filePath string) (*Storage, error) { 19 s := &Storage{ 20 filePath: filePath, 21 posted: make(map[string]bool), 22 } 23 24 // Load existing posted items 25 if err := s.load(); err != nil { 26 return nil, fmt.Errorf("failed to load storage: %w", err) 27 } 28 29 return s, nil 30} 31 32// load reads the posted items from disk 33func (s *Storage) load() error { 34 file, err := os.Open(s.filePath) 35 if err != nil { 36 if os.IsNotExist(err) { 37 // File doesn't exist yet, that's okay 38 return nil 39 } 40 return err 41 } 42 defer file.Close() 43 44 scanner := bufio.NewScanner(file) 45 for scanner.Scan() { 46 guid := scanner.Text() 47 if guid != "" { 48 s.posted[guid] = true 49 } 50 } 51 52 return scanner.Err() 53} 54 55// save writes the posted items to disk 56func (s *Storage) save() error { 57 file, err := os.Create(s.filePath) 58 if err != nil { 59 return err 60 } 61 defer file.Close() 62 63 writer := bufio.NewWriter(file) 64 for guid := range s.posted { 65 if _, err := writer.WriteString(guid + "\n"); err != nil { 66 return err 67 } 68 } 69 70 return writer.Flush() 71} 72 73// IsPosted checks if a GUID has been posted 74func (s *Storage) IsPosted(guid string) bool { 75 s.mu.RLock() 76 defer s.mu.RUnlock() 77 return s.posted[guid] 78} 79 80// MarkPosted marks a GUID as posted 81func (s *Storage) MarkPosted(guid string) error { 82 s.mu.Lock() 83 defer s.mu.Unlock() 84 85 s.posted[guid] = true 86 return s.save() 87} 88 89// Count returns the number of posted items 90func (s *Storage) Count() int { 91 s.mu.RLock() 92 defer s.mu.RUnlock() 93 return len(s.posted) 94}