-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpagefile.go
91 lines (75 loc) · 1.83 KB
/
pagefile.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// SPDX-FileCopyrightText: 2020 Alvar Penning
//
// SPDX-License-Identifier: GPL-3.0-or-later
package pmwiki
import (
"fmt"
"net"
"strings"
"time"
)
// PageFileRevision describes a PageFile internal diff.
type PageFileRevision struct {
Time time.Time
Author string
Host net.IP
Diff Patch
DiffAgainst time.Time
}
// PageFile describes a PmWiki page including its history.
type PageFile struct {
Version string
Name string
Time time.Time
Text string
Author string
Host net.IP
Rev int
Revs map[time.Time]PageFileRevision
Deleted time.Time
}
// Revisions calls a function with a "view" copy of each revision of this PageFile.
//
// An error is returned when creating the successive revision fails. However, multiple previous revisions could be
// generated previously.
func (pageFile PageFile) Revisions(callback func(view PageFile)) error {
if pageFile.Deleted != (time.Time{}) {
defer callback(PageFile{
Version: pageFile.Version,
Name: pageFile.Name,
Time: pageFile.Deleted,
Text: "",
Author: "", // the real author is written in the RecentChanges file
Host: net.ParseIP("::1"),
Rev: pageFile.Rev + 1,
})
}
if len(pageFile.Revs) == 0 {
callback(pageFile)
return nil
}
text := pageFile.Text
revNo := pageFile.Rev
for rev, ok := pageFile.Revs[pageFile.Time]; text != ""; rev, ok = pageFile.Revs[rev.DiffAgainst] {
if !ok {
return fmt.Errorf("revision %d is missing", revNo)
}
curr := PageFile{
Version: pageFile.Version,
Name: pageFile.Name,
Time: rev.Time,
Text: text,
Author: rev.Author,
Host: rev.Host,
Rev: revNo,
}
callback(curr)
revNo--
var textOut strings.Builder
if err := rev.Diff.Apply(strings.NewReader(text), &textOut); err != nil {
return err
}
text = textOut.String()
}
return nil
}