func fakePhotosetsList(sets int) string { var photosets []*photosetInfo for i := 1; i <= sets; i++ { title := fmt.Sprintf("Photoset %d", i) photosetId := blob.RefFromString(title).DigestPrefix(10) primaryPhotoId := blob.RefFromString(fmt.Sprintf("Photo 1 on page 1 of photoset %s", photosetId)).DigestPrefix(10) item := &photosetInfo{ Id: photosetId, PrimaryPhotoId: primaryPhotoId, Title: contentString{Content: title}, Description: contentString{Content: "fakePhotosetDescription"}, } photosets = append(photosets, item) } setslist := struct { Photosets photosetList }{ Photosets: photosetList{ Photoset: photosets, }, } list, err := json.MarshalIndent(&setslist, "", " ") if err != nil { log.Fatalf("%v", err) } return string(list) }
// fakeCheckinsList returns a JSON checkins list of checkinsRequestLimit checkin // items, starting at offset. It stops before checkinsRequestLimit if maxCheckin is // reached. It uses towns to populate the venues. The returned list is saved in // cached. func fakeCheckinsList(offset, maxCheckin int, towns map[int]*venueLocationItem, cached map[int]string) string { if cl, ok := cached[offset]; ok { return cl } max := offset + checkinsRequestLimit if max > maxCheckin { max = maxCheckin } var items []*checkinItem tzCounter := 0 venueCounter := 0 for i := offset; i < max; i++ { shout := fmt.Sprintf("fakeShout %d", i) item := &checkinItem{ Id: blob.RefFromString(shout).DigestPrefix(10), Shout: shout, With: []*user{ { Id: "123", FirstName: "Kate", LastName: "Pek", Photo: photoItem{ Prefix: "https://irs3.4sqi.net/img/user/", Suffix: "/13674-S2IUMHALCCJJUTQO.jpg", }, }, }, CreatedAt: time.Now().Unix(), TimeZoneOffset: tzCounter * 60, Venue: fakeVenue(venueCounter, towns), } items = append(items, item) tzCounter++ venueCounter++ if tzCounter == 24 { tzCounter = 0 } if venueCounter == 5 { venueCounter = 0 } } response := struct { Checkins struct { Items []*checkinItem } }{ Checkins: struct { Items []*checkinItem }{ Items: items, }, } list, err := json.MarshalIndent(checkinsList{Response: response}, "", " ") if err != nil { log.Fatalf("%v", err) } cached[offset] = string(list) return cached[offset] }
func fakePhotoEntry(photoNbr int, albumNbr int) picago.Entry { var content picago.EntryContent if photoNbr%2 == 0 { content = picago.EntryContent{ URL: "https://camlistore.org/pic/pudgy1.png", Type: "image/png", } } var point string if photoNbr%3 == 0 { point = "37.7447124 -122.4341914" } else { point = "45.1822842 5.7141854" } mediaContent := picago.MediaContent{ URL: "https://camlistore.org/pic/pudgy2.png", Type: "image/png", } media := &picago.Media{ Title: "fakePhotoTitle", Description: "fakePhotoDescription", Keywords: "fakeKeyword1,fakeKeyword2", Content: []picago.MediaContent{mediaContent}, } // to be consistent, all the pics times should be anterior to their respective albums times. whatever. day := time.Hour * 24 year := day * 365 created := time.Now().Add(-time.Duration(photoNbr) * year) published := created.Add(day) updated := published.Add(day) exif := &picago.Exif{ FStop: 7.7, Make: "whatisthis?", // not obvious to me, needs doc in picago Model: "potato", Exposure: 7.7, Flash: false, FocalLength: 7.7, ISO: 100, Timestamp: created.Unix(), UID: "whatisthis?", // not obvious to me, needs doc in picago } title := fmt.Sprintf("Photo %d of album %d", photoNbr, albumNbr) return picago.Entry{ ID: blob.RefFromString(title).DigestPrefix(10), Exif: exif, Summary: "fakePhotoSummary", Title: title, Location: "fakePhotoLocation", Published: published, Updated: updated, Media: media, Point: point, Content: content, } }
func fakePhotoItem() *photoItem { prefix := "https://camlistore.org/" suffix := "/pic/pudgy.png" return &photoItem{ Id: blob.RefFromString(prefix + suffix).DigestPrefix(10), Prefix: prefix, Suffix: suffix, Width: 704, Height: 186, } }
// fakeCheckinsList returns a JSON checkins list of checkinsRequestLimit checkin // items, starting at offset. It stops before checkinsRequestLimit if maxCheckin is // reached. It uses towns to populate the venues. The returned list is saved in // cached. func fakeCheckinsList(offset, maxCheckin int, towns map[int]*venueLocationItem, cached map[int]string) string { if cl, ok := cached[offset]; ok { return cl } max := offset + checkinsRequestLimit if max > maxCheckin { max = maxCheckin } var items []*checkinItem tzCounter := 0 venueCounter := 0 for i := offset; i < max; i++ { shout := fmt.Sprintf("fakeShout %d", i) item := &checkinItem{ Id: blob.RefFromString(shout).DigestPrefix(10), Shout: shout, CreatedAt: time.Now().Unix(), TimeZoneOffset: tzCounter * 60, Venue: fakeVenue(venueCounter, towns), } items = append(items, item) tzCounter++ venueCounter++ if tzCounter == 24 { tzCounter = 0 } if venueCounter == 5 { venueCounter = 0 } } response := struct { Checkins struct { Items []*checkinItem } }{ Checkins: struct { Items []*checkinItem }{ Items: items, }, } list, err := json.MarshalIndent(checkinsList{Response: response}, "", " ") if err != nil { log.Fatalf("%v", err) } cached[offset] = string(list) return cached[offset] }
func (im *imp) MakeTestData() http.RoundTripper { const ( apiURL = "https://picasaweb.google.com/data/feed/api" nAlbums = 10 // Arbitrary number of albums generated. nEntries = 3 // number of albums or photos returned in the feed at each call. defaultUserId = "default" ) albumsListCached := make(map[int]string) okHeader := `HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 ` responses := make(map[string]func() *http.Response) // register the get albums list calls for i := 1; i < nAlbums+1; i += nEntries { url := fmt.Sprintf("%s/user/%s?start-index=%d", apiURL, defaultUserId, i) response := okHeader + fakeAlbumsList(i, nAlbums, nEntries, albumsListCached) responses[url] = httputil.StaticResponder(response) } // register the get album calls for i := 1; i < nAlbums+1; i++ { albumId := blob.RefFromString(fmt.Sprintf("Album %d", i)).DigestPrefix(10) for j := 1; j < i+1; j += nEntries { url := fmt.Sprintf("%s/user/%s/albumid/%s?imgmax=d&start-index=%d", apiURL, defaultUserId, albumId, j) // Using i as nTotal argument means album N will have N photos in it. response := okHeader + fakePhotosList(j, i, nEntries) responses[url] = httputil.StaticResponder(response) } } // register the photo download calls pudgyPic := fakePhoto() photoURL1 := "https://camlistore.org/pic/pudgy1.png" photoURL2 := "https://camlistore.org/pic/pudgy2.png" responses[photoURL1] = httputil.FileResponder(pudgyPic) responses[photoURL2] = httputil.FileResponder(pudgyPic) return httputil.NewFakeTransport(responses) }
func fakeVenue(counter int, towns map[int]*venueLocationItem) venueItem { prefix := "https://camlistore.org/" suffix := "/pic/pudgy.png" // TODO: add more. categories := []*venueCategory{ { Primary: true, Name: "town", Icon: &categoryIcon{ Prefix: prefix, Suffix: suffix, }, }, } return venueItem{ Id: blob.RefFromString(towns[counter].City).DigestPrefix(10), Name: towns[counter].City, Location: towns[counter], Categories: categories, } }
func fakeAlbum(counter int) picago.Entry { author := picago.Author{ Name: "fakeAuthorName", } media := &picago.Media{ Description: "fakeAlbumDescription", Keywords: "fakeKeyword1,fakeKeyword2", } title := fmt.Sprintf("Album %d", counter) year := time.Hour * 24 * 365 month := year / 12 return picago.Entry{ ID: blob.RefFromString(title).DigestPrefix(10), Published: time.Now().Add(-time.Duration(counter) * year), Updated: time.Now().Add(-time.Duration(counter) * month), Name: "fakeAlbumName", Title: title, Summary: "fakeAlbumSummary", Location: "fakeAlbumLocation", Author: author, Media: media, } }
func (im *imp) MakeTestData() http.RoundTripper { const nCheckins = 150 // Arbitrary number of checkins generated. // if you add another venue, make sure the venueCounter reset // in fakeCheckinsList allows for that case to happen. // We could use global vars instead, but don't want to pollute the // fousquare pkg namespace. towns := map[int]*venueLocationItem{ 0: { Address: "Baker street", City: "Dublin", PostalCode: "0", State: "none", Country: "Ireland", Lat: 53.4053427, Lng: -8.3320801, }, 1: { Address: "Fish&Ships street", City: "London", PostalCode: "1", State: "none", Country: "England", Lat: 55.3617609, Lng: -3.4433238, }, 2: { Address: "Haggis street", City: "Glasgow", PostalCode: "2", State: "none", Country: "Scotland", Lat: 57.7394571, Lng: -4.686997, }, 3: { Address: "rue du croissant", City: "Grenoble", PostalCode: "38000", State: "none", Country: "France", Lat: 45.1841655, Lng: 5.7155424, }, 4: { Address: "burrito street", City: "San Francisco", PostalCode: "94114", State: "CA", Country: "US", Lat: 37.7593625, Lng: -122.4266995, }, } // We need to compute the venueIds in advance, because the venue id is used as a parameter // in some of the requests we need to register. var venueIds []string for _, v := range towns { venueIds = append(venueIds, blob.RefFromString(v.City).DigestPrefix(10)) } checkinsURL := apiURL + checkinsAPIPath checkinsListCached := make(map[int]string) okHeader := `HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 ` responses := make(map[string]func() *http.Response) // register all the checkins calls; offset varies. for i := 0; i < nCheckins; i += checkinsRequestLimit { url := fmt.Sprintf("%s?limit=%d&oauth_token=fakeAccessToken&offset=%d&v=%s", checkinsURL, checkinsRequestLimit, i, apiVersion) response := okHeader + fakeCheckinsList(i, nCheckins, towns, checkinsListCached) responses[url] = httputil.StaticResponder(response) } // register all the venue photos calls (venueId varies) photosURL := apiURL + "venues" photosResponse := okHeader + fakePhotosList() for _, id := range venueIds { url := fmt.Sprintf("%s/%s/photos?limit=%d&oauth_token=fakeAccessToken&v=%s", photosURL, id, photosRequestLimit, apiVersion) responses[url] = httputil.StaticResponder(photosResponse) } // register the photoitem calls pudgyPic := fakePhoto() photoURL := "https://camlistore.org/pic/pudgy.png" originalPhotoURL := "https://camlistore.org/original/pic/pudgy.png" iconURL := "https://camlistore.org/bg_88/pic/pudgy.png" responses[photoURL] = httputil.FileResponder(pudgyPic) responses[originalPhotoURL] = httputil.FileResponder(pudgyPic) responses[iconURL] = httputil.FileResponder(pudgyPic) return httputil.NewFakeTransport(responses) }
func (im imp) MakeTestData() http.RoundTripper { const ( nPhotosets = 5 // Arbitrary number of sets. perPage = 3 // number of photos per page (both when getting sets and when getting photos). fakeUserId = "fakeUserId" ) // Photoset N has N photos, so we've got 15 ( = 5 + 4 + 3 + 2 + 1) photos in total. var nPhotos int for i := 1; i <= nPhotosets; i++ { nPhotos += i } nPhotosPages := nPhotos / perPage if nPhotos%perPage != 0 { nPhotosPages++ } okHeader := `HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 ` // TODO(mpl): this scheme does not take into account that we could have the same photo // in different albums. These two photos will end up with a different photoId. buildPhotoIds := func(nsets, perPage int) []string { var ids []string for i := 1; i <= nsets; i++ { photosetId := blob.RefFromString(fmt.Sprintf("Photoset %d", i)).DigestPrefix(10) page := 1 // Photoset N has N photos. indexOnPage := 1 for j := 1; j <= i; j++ { photoId := blob.RefFromString(fmt.Sprintf("Photo %d on page %d of photoset %s", indexOnPage, page, photosetId)).DigestPrefix(10) ids = append(ids, photoId) indexOnPage++ if indexOnPage > perPage { page++ indexOnPage = 1 } } } return ids } photoIds := buildPhotoIds(nPhotosets, perPage) responses := make(map[string]func() *http.Response) // Initial photo sets list photosetsURL := fmt.Sprintf("%s?format=json&method=%s&nojsoncallback=1&user_id=%s", apiURL, photosetsAPIPath, fakeUserId) response := fmt.Sprintf("%s%s", okHeader, fakePhotosetsList(nPhotosets)) responses[photosetsURL] = httputil.StaticResponder(response) // All the photoset calls. One call for each page of each photoset. // Each page as perPage photos, or maybe less if end of the photoset. { pageStart := 0 albumEnd, pageEnd, albumNum, pages, page := 1, 1, 1, 1, 1 photosetId := blob.RefFromString(fmt.Sprintf("Photoset %d", albumNum)).DigestPrefix(10) photosURL := fmt.Sprintf("%s?extras=original_format&format=json&method=%s&nojsoncallback=1&page=%d&photoset_id=%s&user_id=%s", apiURL, photosetAPIPath, page, photosetId, fakeUserId) response := fmt.Sprintf("%s%s", okHeader, fakePhotoset(photosetId, page, pages, photoIds[pageStart:pageEnd])) responses[photosURL] = httputil.StaticResponder(response) for k, _ := range photoIds { if k < pageEnd { continue } page++ pageStart = k pageEnd = k + perPage if page > pages { albumNum++ page = 1 pages = albumNum / perPage if albumNum%perPage != 0 { pages++ } albumEnd = pageStart + albumNum photosetId = blob.RefFromString(fmt.Sprintf("Photoset %d", albumNum)).DigestPrefix(10) } if pageEnd > albumEnd { pageEnd = albumEnd } photosURL := fmt.Sprintf("%s?extras=original_format&format=json&method=%s&nojsoncallback=1&page=%d&photoset_id=%s&user_id=%s", apiURL, photosetAPIPath, page, photosetId, fakeUserId) response := fmt.Sprintf("%s%s", okHeader, fakePhotoset(photosetId, page, pages, photoIds[pageStart:pageEnd])) responses[photosURL] = httputil.StaticResponder(response) } } // All the photo page calls (to get the photos info). // Each page has perPage photos, until end of photos. for i := 1; i <= nPhotosPages; i++ { photosURL := fmt.Sprintf("%s?extras=", apiURL) + url.QueryEscape("description,date_upload,date_taken,original_format,last_update,geo,tags,machine_tags,views,media,url_o") + fmt.Sprintf("&format=json&method=%s&nojsoncallback=1&page=%d&user_id=%s", photosAPIPath, i, fakeUserId) response := fmt.Sprintf("%s%s", okHeader, fakePhotosPage(i, nPhotosPages, perPage, photoIds)) responses[photosURL] = httputil.StaticResponder(response) } // Actual photo(s) URL. pudgyPic := fakePicture() for _, v := range photoIds { photoURL := fmt.Sprintf("https://farm3.staticflickr.com/2897/14198397111_%s_o.jpg?user_id=%s", v, fakeUserId) responses[photoURL] = httputil.FileResponder(pudgyPic) } return httputil.NewFakeTransport(responses) }
// IsDir reports whether root is a localdisk (file-per-blob) storage directory. func IsDir(root string) (bool, error) { if osutil.DirExists(filepath.Join(root, blob.RefFromString("").HashName())) { return true, nil } return false, nil }
// ReceiveString uploads the blob given by the string s to dst // and returns its blobref and size. func ReceiveString(dst BlobReceiver, s string) (blob.SizedRef, error) { return Receive(dst, blob.RefFromString(s), strings.NewReader(s)) }