1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16
17
18 package dummy
19
20 import (
21 "fmt"
22 "log"
23 "math/rand"
24 "net/http"
25 "net/url"
26 "strconv"
27 "strings"
28
29 "perkeep.org/internal/httputil"
30 "perkeep.org/pkg/blob"
31 "perkeep.org/pkg/env"
32 "perkeep.org/pkg/importer"
33 "perkeep.org/pkg/schema"
34 )
35
36 func init() {
37 if !env.IsDev() {
38
39
40
41 return
42 }
43
44
45
46
47
48 importer.Register("dummy", &imp{})
49 }
50
51
52
53
54
55 type imp struct {
56
57
58
59
60
61
62
63
64 }
65
66 func (*imp) Properties() importer.Properties {
67 return importer.Properties{
68
69
70
71
72
73
74 NeedsAPIKey: true,
75
76
77
78
79
80 SupportsIncremental: false,
81 }
82 }
83
84 const (
85 acctAttrToken = "my_token"
86 acctAttrUsername = "username"
87 acctAttrRunNumber = "run_number"
88 )
89
90 func (*imp) IsAccountReady(acct *importer.Object) (ready bool, err error) {
91
92
93
94
95 return acct.Attr(acctAttrToken) != "" && acct.Attr(acctAttrUsername) != "", nil
96 }
97
98 func (*imp) SummarizeAccount(acct *importer.Object) string {
99
100
101
102 return acct.Attr(acctAttrUsername)
103 }
104
105 func (*imp) ServeSetup(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) error {
106
107
108
109
110
111 http.Redirect(w, r, ctx.CallbackURL(), http.StatusFound)
112 return nil
113 }
114
115
116
117
118
119
120
121
122 var _ importer.ImporterSetupHTMLer = (*imp)(nil)
123
124 func (im *imp) AccountSetupHTML(host *importer.Host) string {
125 return "<h1>Hello from the dummy importer!</h1><p>I am example HTML. This importer is a demo of how to write an importer.</p>"
126 }
127
128 func (im *imp) ServeCallback(w http.ResponseWriter, r *http.Request, ctx *importer.SetupContext) {
129
130
131
132 code := r.FormValue("code")
133 if code == "" {
134 code = "some_dummy_code"
135 }
136 name := ctx.AccountNode.Attr(acctAttrUsername)
137 if name == "" {
138 names := []string{
139 "alfred", "alice", "bob", "bethany",
140 "cooper", "claire", "doug", "darla",
141 "ed", "eve", "frank", "francine",
142 }
143 name = names[rand.Intn(len(names))]
144 }
145 if err := ctx.AccountNode.SetAttrs(
146 "title", fmt.Sprintf("dummy account: %s", name),
147 acctAttrUsername, name,
148 acctAttrToken, code,
149 ); err != nil {
150 httputil.ServeError(w, r, fmt.Errorf("Error setting attributes: %v", err))
151 return
152 }
153 http.Redirect(w, r, ctx.AccountURL(), http.StatusFound)
154 }
155
156 func (im *imp) Run(ctx *importer.RunContext) (err error) {
157 log.Printf("Running dummy importer.")
158 defer func() {
159 log.Printf("Dummy importer returned: %v", err)
160 }()
161 root := ctx.RootNode()
162 fileRef, err := schema.WriteFileFromReader(ctx.Context(), ctx.Host.Target(), "foo.txt", strings.NewReader("Some file.\n"))
163 if err != nil {
164 return err
165 }
166 obj, err := root.ChildPathObject("foo.txt")
167 if err != nil {
168 return err
169 }
170 if err = obj.SetAttr("camliContent", fileRef.String()); err != nil {
171 return err
172 }
173 n, _ := strconv.Atoi(ctx.AccountNode().Attr(acctAttrRunNumber))
174 n++
175 ctx.AccountNode().SetAttr(acctAttrRunNumber, fmt.Sprint(n))
176
177
178 return root.SetAttr("title", fmt.Sprintf("dummy: %s import #%d", ctx.AccountNode().Attr(acctAttrUsername), n))
179 }
180
181 func (im *imp) ServeHTTP(w http.ResponseWriter, r *http.Request) {
182 httputil.BadRequestError(w, "Unexpected path: %s", r.URL.Path)
183 }
184
185 func (im *imp) CallbackRequestAccount(r *http.Request) (blob.Ref, error) {
186
187
188
189
190 return importer.OAuth1{}.CallbackRequestAccount(r)
191 }
192
193 func (im *imp) CallbackURLParameters(acctRef blob.Ref) url.Values {
194
195 return importer.OAuth1{}.CallbackURLParameters(acctRef)
196 }