diff --git a/core/core.go b/core/core.go new file mode 100644 index 0000000..7a3dd40 --- /dev/null +++ b/core/core.go @@ -0,0 +1,63 @@ +// Copyright (C) 2021 nytpu +// SPDX-License-Identifier: AGPL-3.0-or-later +// For more license details, see LICENSE or . + +// This file incorporates code from makeworld's amfora: +// https://github.com/makeworld-the-better-one/amfora/blob/master/subscriptions/structs.go +// Original source is Copyright 2020 makeworld and is licensed under the +// terms of the GNU General Public License Version 3.0. +// https://www.gnu.org/licenses/gpl-3.0-standalone.html + +// package core implements the structs and other necessary resources for storing +// and managing feeds and pages +package core + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/url" + "os" + "path/filepath" + "sync" +) + +// Global instance of FullData +var Data = FullData{ + FeedsMu: &sync.RWMutex{}, + PagesMu: &sync.RWMutex{}, + // Maps are created in init() +} + +// have to do this instead of the automatically called init() because +// initialization stuff requires parsing of command line args first +func Init(dataPath string) error { + f, err := os.Open(filepath.Join(dataPath, "comitium.json")) + if err == nil { + // File exists and could be opened + fi, err := f.Stat() + if err == nil && fi.Size() > 0 { + // File is not empty + jsonBytes, err := ioutil.ReadAll(f) + f.Close() + if err != nil { + return fmt.Errorf("read comitium.json error: %w", err) + } + err = json.Unmarshal(jsonBytes, &Data) + if err != nil { + return fmt.Errorf("comitium.json is corrupted: %w", err) + } + } + f.Close() + } else if !os.IsNotExist(err) { + // There's an error opening the file, but it's not bc is doesn't exist + return fmt.Errorf("open comitium.json error: %w", err) + } + + if Data.Feeds == nil { + Data.Feeds = make(map[url.URL]*Feed) + } + if Data.Pages == nil { + Data.Pages = make(map[url.URL]*Page) + } +} diff --git a/core/structs.go b/core/structs.go index abebed0..28915e1 100644 --- a/core/structs.go +++ b/core/structs.go @@ -8,8 +8,6 @@ // terms of the GNU General Public License Version 3.0. // https://www.gnu.org/licenses/gpl-3.0-standalone.html -// package core implements the structs and other necessary resources for storing -// and managing feeds and pages package core import ( @@ -110,6 +108,30 @@ func (f *Feed) Swap(i, j int) { f.Items[i], f.Items[j] = f.Items[j], f.Items[i] } +// Lock locks both feed and page mutexes. +func (j *JsonData) Lock() { + j.FeedsMu.Lock() + j.PagesMu.Lock() +} + +// Unlock unlocks both feed and page mutexes. +func (j *JsonData) Unlock() { + j.FeedsMu.Unlock() + j.PagesMu.Unlock() +} + +// RLock read-locks both feed and page mutexes. +func (j *JsonData) RLock() { + j.FeedsMu.RLock() + j.PagesMu.RLock() +} + +// RUnlock read-unlocks both feed and page mutexes. +func (j *JsonData) RUnlock() { + j.FeedsMu.RUnlock() + j.PagesMu.RUnlock() +} + // PageEntry is a single item on a subscriptions page. It is used for both feeds // and pages. type PageEntry struct {