7 "github.com/jhalter/mobius/hotline"
15 type ThreadedNewsYAML struct {
16 ThreadedNews hotline.ThreadedNews
23 func NewThreadedNewsYAML(filePath string) (*ThreadedNewsYAML, error) {
24 tn := &ThreadedNewsYAML{filePath: filePath}
31 func (n *ThreadedNewsYAML) CreateGrouping(newsPath []string, name string, t [2]byte) error {
35 cats := n.getCatByPath(newsPath)
36 cats[name] = hotline.NewsCategoryListData15{
39 Articles: map[uint32]*hotline.NewsArtData{},
40 SubCats: make(map[string]hotline.NewsCategoryListData15),
46 func (n *ThreadedNewsYAML) NewsItem(newsPath []string) hotline.NewsCategoryListData15 {
50 cats := n.ThreadedNews.Categories
51 delName := newsPath[len(newsPath)-1]
52 if len(newsPath) > 1 {
53 for _, fp := range newsPath[0 : len(newsPath)-1] {
54 cats = cats[fp].SubCats
61 func (n *ThreadedNewsYAML) DeleteNewsItem(newsPath []string) error {
65 cats := n.ThreadedNews.Categories
66 delName := newsPath[len(newsPath)-1]
67 if len(newsPath) > 1 {
68 for _, fp := range newsPath[0 : len(newsPath)-1] {
69 cats = cats[fp].SubCats
78 func (n *ThreadedNewsYAML) GetArticle(newsPath []string, articleID uint32) *hotline.NewsArtData {
82 var cat hotline.NewsCategoryListData15
83 cats := n.ThreadedNews.Categories
85 for _, fp := range newsPath {
87 cats = cats[fp].SubCats
90 art := cat.Articles[articleID]
98 func (n *ThreadedNewsYAML) GetCategories(paths []string) []hotline.NewsCategoryListData15 {
102 var categories []hotline.NewsCategoryListData15
103 for _, c := range n.getCatByPath(paths) {
104 categories = append(categories, c)
107 slices.SortFunc(categories, func(a, b hotline.NewsCategoryListData15) int {
117 func (n *ThreadedNewsYAML) getCatByPath(paths []string) map[string]hotline.NewsCategoryListData15 {
118 cats := n.ThreadedNews.Categories
119 for _, path := range paths {
120 cats = cats[path].SubCats
126 func (n *ThreadedNewsYAML) PostArticle(newsPath []string, parentArticleID uint32, article hotline.NewsArtData) error {
130 binary.BigEndian.PutUint32(article.ParentArt[:], parentArticleID)
132 cats := n.getCatByPath(newsPath[:len(newsPath)-1])
134 catName := newsPath[len(newsPath)-1]
138 for k := range cat.Articles {
139 keys = append(keys, int(k))
145 prevID := uint32(keys[len(keys)-1])
148 binary.BigEndian.PutUint32(article.PrevArt[:], prevID)
150 // Set next article Type
151 binary.BigEndian.PutUint32(cat.Articles[prevID].NextArt[:], nextID)
154 // Update parent article with first child reply
155 parentID := parentArticleID
157 parentArt := cat.Articles[parentID]
159 if parentArt.FirstChildArt == [4]byte{0, 0, 0, 0} {
160 binary.BigEndian.PutUint32(parentArt.FirstChildArt[:], nextID)
164 cat.Articles[nextID] = &article
171 func (n *ThreadedNewsYAML) DeleteArticle(newsPath []string, articleID uint32, _ bool) error {
176 // // TODO: Handle delete recursive
179 cats := n.getCatByPath(newsPath[:len(newsPath)-1])
181 catName := newsPath[len(newsPath)-1]
184 delete(cat.Articles, articleID)
190 func (n *ThreadedNewsYAML) ListArticles(newsPath []string) hotline.NewsArtListData {
194 var cat hotline.NewsCategoryListData15
195 cats := n.ThreadedNews.Categories
197 for _, fp := range newsPath {
199 cats = cats[fp].SubCats
202 return cat.GetNewsArtListData()
205 func (n *ThreadedNewsYAML) Load() error {
209 fh, err := os.Open(n.filePath)
215 n.ThreadedNews = hotline.ThreadedNews{}
217 return yaml.NewDecoder(fh).Decode(&n.ThreadedNews)
220 func (n *ThreadedNewsYAML) writeFile() error {
221 out, err := yaml.Marshal(&n.ThreadedNews)
226 // Define a temporary file path in the same directory.
227 tempFilePath := n.filePath + ".tmp"
229 // Write the marshaled YAML to the temporary file.
230 if err := os.WriteFile(tempFilePath, out, 0644); err != nil {
231 return fmt.Errorf("write to temporary file: %v", err)
234 // Atomically rename the temporary file to the final file path.
235 if err := os.Rename(tempFilePath, n.filePath); err != nil {
236 return fmt.Errorf("rename temporary file to final file: %v", err)