1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16
17 package picasa
18
19 import (
20 "encoding/xml"
21 "fmt"
22 "log"
23 "net/http"
24 "os"
25 "path/filepath"
26 "time"
27
28 "perkeep.org/internal/httputil"
29 "perkeep.org/internal/osutil"
30 "perkeep.org/pkg/blob"
31 "perkeep.org/pkg/importer"
32
33 "github.com/tgulacsi/picago"
34 )
35
36 var _ importer.TestDataMaker = (*imp)(nil)
37
38 func (im *imp) SetTestAccount(acctNode *importer.Object) error {
39
40 return acctNode.SetAttrs(
41 importer.AcctAttrAccessToken, "fakeAccessToken",
42 importer.AcctAttrAccessTokenSecret, "fakeAccessSecret",
43 importer.AcctAttrUserID, "fakeUserId",
44 importer.AcctAttrName, "fakeName",
45 importer.AcctAttrUserName, "fakeScreenName",
46 )
47 }
48
49 func (im *imp) MakeTestData() http.RoundTripper {
50
51 const (
52 apiURL = "https://picasaweb.google.com/data/feed/api"
53 nAlbums = 10
54 nEntries = 3
55 defaultUserId = "default"
56 )
57
58 albumsListCached := make(map[int]string)
59 okHeader := `HTTP/1.1 200 OK
60 Content-Type: application/json; charset=UTF-8
61
62 `
63
64 responses := make(map[string]func() *http.Response)
65
66
67 for i := 1; i < nAlbums+1; i += nEntries {
68 url := fmt.Sprintf("%s/user/%s?start-index=%d", apiURL, defaultUserId, i)
69 response := okHeader + fakeAlbumsList(i, nAlbums, nEntries, albumsListCached)
70 responses[url] = httputil.StaticResponder(response)
71 }
72
73
74 for i := 1; i < nAlbums+1; i++ {
75 albumId := blob.RefFromString(fmt.Sprintf("Album %d", i)).DigestPrefix(10)
76 for j := 1; j < i+1; j += nEntries {
77 url := fmt.Sprintf("%s/user/%s/albumid/%s?imgmax=d&start-index=%d", apiURL, defaultUserId, albumId, j)
78
79 response := okHeader + fakePhotosList(j, i, nEntries)
80 responses[url] = httputil.StaticResponder(response)
81 }
82 }
83
84
85 pudgyPic := fakePhoto()
86 photoURL1 := "https://perkeep.org/pic/pudgy1.png"
87 photoURL2 := "https://perkeep.org/pic/pudgy2.png"
88 responses[photoURL1] = httputil.FileResponder(pudgyPic)
89 responses[photoURL2] = httputil.FileResponder(pudgyPic)
90
91 return httputil.NewFakeTransport(responses)
92 }
93
94
95
96
97 func fakeAlbumsList(index, nTotal, nEntries int, cached map[int]string) string {
98 if cl, ok := cached[index]; ok {
99 return cl
100 }
101
102 max := index + nEntries
103 if max > nTotal+1 {
104 max = nTotal + 1
105 }
106 var entries []picago.Entry
107 for i := index; i < max; i++ {
108 entries = append(entries, fakeAlbum(i))
109 }
110 atom := &picago.Atom{
111 TotalResults: nTotal,
112 Entries: entries,
113 }
114
115 feed, err := xml.MarshalIndent(atom, "", " ")
116 if err != nil {
117 log.Fatalf("%v", err)
118 }
119 cached[index] = string(feed)
120 return cached[index]
121 }
122
123 func fakeAlbum(counter int) picago.Entry {
124 author := picago.Author{
125 Name: "fakeAuthorName",
126 }
127 media := &picago.Media{
128 Description: "fakeAlbumDescription",
129 Keywords: "fakeKeyword1,fakeKeyword2",
130 }
131 title := fmt.Sprintf("Album %d", counter)
132 year := time.Hour * 24 * 365
133 month := year / 12
134 return picago.Entry{
135 ID: blob.RefFromString(title).DigestPrefix(10),
136 Published: time.Now().Add(-time.Duration(counter) * year),
137 Updated: time.Now().Add(-time.Duration(counter) * month),
138 Name: "fakeAlbumName",
139 Title: title,
140 Summary: "fakeAlbumSummary",
141 Location: "fakeAlbumLocation",
142 Author: author,
143 Media: media,
144 }
145 }
146
147
148
149
150 func fakePhotosList(index, nTotal, nEntries int) string {
151 max := index + nEntries
152 if max > nTotal+1 {
153 max = nTotal + 1
154 }
155 var entries []picago.Entry
156 for i := index; i < max; i++ {
157 entries = append(entries, fakePhotoEntry(i, nTotal))
158 }
159 atom := &picago.Atom{
160 NumPhotos: nTotal,
161 Entries: entries,
162 }
163
164 feed, err := xml.MarshalIndent(atom, "", " ")
165 if err != nil {
166 log.Fatalf("%v", err)
167 }
168 return string(feed)
169 }
170
171 func fakePhotoEntry(photoNbr int, albumNbr int) picago.Entry {
172 var content picago.EntryContent
173 if photoNbr%2 == 0 {
174 content = picago.EntryContent{
175 URL: "https://perkeep.org/pic/pudgy1.png",
176 Type: "image/png",
177 }
178 }
179 var point string
180 if photoNbr%3 == 0 {
181 point = "37.7447124 -122.4341914"
182 } else {
183 point = "45.1822842 5.7141854"
184 }
185 mediaContent := picago.MediaContent{
186 URL: "https://perkeep.org/pic/pudgy2.png",
187 Type: "image/png",
188 }
189 media := &picago.Media{
190 Title: "fakePhotoTitle",
191 Description: "fakePhotoDescription",
192 Keywords: "fakeKeyword1,fakeKeyword2",
193 Content: []picago.MediaContent{mediaContent},
194 }
195
196 day := time.Hour * 24
197 year := day * 365
198 created := time.Now().Add(-time.Duration(photoNbr) * year)
199 published := created.Add(day)
200 updated := published.Add(day)
201
202 exif := &picago.Exif{
203 FStop: 7.7,
204 Make: "whatisthis?",
205 Model: "potato",
206 Exposure: 7.7,
207 Flash: false,
208 FocalLength: 7.7,
209 ISO: 100,
210 Timestamp: created.Unix(),
211 UID: "whatisthis?",
212 }
213
214 title := fmt.Sprintf("Photo %d of album %d", photoNbr, albumNbr)
215 return picago.Entry{
216 ID: blob.RefFromString(title).DigestPrefix(10),
217 Exif: exif,
218 Summary: "fakePhotoSummary",
219 Title: title,
220 Location: "fakePhotoLocation",
221 Published: published,
222 Updated: updated,
223 Media: media,
224 Point: point,
225 Content: content,
226 }
227 }
228
229
230 func fakePhoto() string {
231 camliDir, err := osutil.GoPackagePath("perkeep.org")
232 if err == os.ErrNotExist {
233 log.Fatal("Directory \"perkeep.org\" not found under GOPATH/src; are you not running with devcam?")
234 }
235 if err != nil {
236 log.Fatalf("Error searching for \"perkeep.org\" under GOPATH: %v", err)
237 }
238 return filepath.Join(camliDir, filepath.FromSlash("clients/web/embed/glitch/npc_piggy__x1_walk_png_1354829432.png"))
239 }