Home Download Docs Code Community
     1	/*
     2	Copyright 2014 The Perkeep Authors
     3	
     4	Licensed under the Apache License, Version 2.0 (the "License");
     5	you may not use this file except in compliance with the License.
     6	You may obtain a copy of the License at
     7	
     8	     http://www.apache.org/licenses/LICENSE-2.0
     9	
    10	Unless required by applicable law or agreed to in writing, software
    11	distributed under the License is distributed on an "AS IS" BASIS,
    12	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13	See the License for the specific language governing permissions and
    14	limitations under the License.
    15	*/
    16	
    17	package swarm
    18	
    19	import (
    20		"encoding/json"
    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	
    34	var _ importer.TestDataMaker = (*imp)(nil)
    35	
    36	func (im *imp) SetTestAccount(acctNode *importer.Object) error {
    37		// TODO(mpl): refactor with twitter
    38		return acctNode.SetAttrs(
    39			importer.AcctAttrAccessToken, "fakeAccessToken",
    40			importer.AcctAttrAccessTokenSecret, "fakeAccessSecret",
    41			importer.AcctAttrUserID, "fakeUserID",
    42			importer.AcctAttrName, "fakeName",
    43			importer.AcctAttrUserName, "fakeScreenName",
    44		)
    45	}
    46	
    47	func (im *imp) MakeTestData() http.RoundTripper {
    48	
    49		const nCheckins = 150 // Arbitrary number of checkins generated.
    50	
    51		// if you add another venue, make sure the venueCounter reset
    52		// in fakeCheckinsList allows for that case to happen.
    53		// We could use global vars instead, but don't want to pollute the
    54		// fousquare pkg namespace.
    55		towns := map[int]*venueLocationItem{
    56			0: {
    57				Address:    "Baker street",
    58				City:       "Dublin",
    59				PostalCode: "0",
    60				State:      "none",
    61				Country:    "Ireland",
    62				Lat:        53.4053427,
    63				Lng:        -8.3320801,
    64			},
    65			1: {
    66				Address:    "Fish&Ships street",
    67				City:       "London",
    68				PostalCode: "1",
    69				State:      "none",
    70				Country:    "England",
    71				Lat:        55.3617609,
    72				Lng:        -3.4433238,
    73			},
    74			2: {
    75				Address:    "Haggis street",
    76				City:       "Glasgow",
    77				PostalCode: "2",
    78				State:      "none",
    79				Country:    "Scotland",
    80				Lat:        57.7394571,
    81				Lng:        -4.686997,
    82			},
    83			3: {
    84				Address:    "rue du croissant",
    85				City:       "Grenoble",
    86				PostalCode: "38000",
    87				State:      "none",
    88				Country:    "France",
    89				Lat:        45.1841655,
    90				Lng:        5.7155424,
    91			},
    92			4: {
    93				Address:    "burrito street",
    94				City:       "San Francisco",
    95				PostalCode: "94114",
    96				State:      "CA",
    97				Country:    "US",
    98				Lat:        37.7593625,
    99				Lng:        -122.4266995,
   100			},
   101		}
   102	
   103		// We need to compute the venueIds in advance, because the venue id is used as a parameter
   104		// in some of the requests we need to register.
   105		var venueIds []string
   106		for _, v := range towns {
   107			venueIds = append(venueIds, blob.RefFromString(v.City).DigestPrefix(10))
   108		}
   109	
   110		checkinsURL := apiURL + checkinsAPIPath
   111		checkinsListCached := make(map[int]string)
   112		okHeader := `HTTP/1.1 200 OK
   113	Content-Type: application/json; charset=UTF-8
   114	
   115	`
   116	
   117		responses := make(map[string]func() *http.Response)
   118	
   119		// register all the checkins calls; offset varies.
   120		for i := 0; i < nCheckins; i += checkinsRequestLimit {
   121			url := fmt.Sprintf("%s?limit=%d&oauth_token=fakeAccessToken&offset=%d&v=%s",
   122				checkinsURL, checkinsRequestLimit, i, apiVersion)
   123			response := okHeader + fakeCheckinsList(i, nCheckins, towns, checkinsListCached)
   124			responses[url] = httputil.StaticResponder(response)
   125		}
   126	
   127		// register all the venue photos calls (venueId varies)
   128		photosURL := apiURL + "venues"
   129		photosResponse := okHeader + fakePhotosList()
   130		for _, id := range venueIds {
   131			url := fmt.Sprintf("%s/%s/photos?limit=%d&oauth_token=fakeAccessToken&v=%s",
   132				photosURL, id, photosRequestLimit, apiVersion)
   133			responses[url] = httputil.StaticResponder(photosResponse)
   134		}
   135	
   136		// register the photoitem calls
   137		pudgyPic := fakePhoto()
   138		photoURL := "https://perkeep.org/pic/pudgy.png"
   139		originalPhotoURL := "https://perkeep.org/original/pic/pudgy.png"
   140		iconURL := "https://perkeep.org/bg_88/pic/pudgy.png"
   141		responses[photoURL] = httputil.FileResponder(pudgyPic)
   142		responses[originalPhotoURL] = httputil.FileResponder(pudgyPic)
   143		responses[iconURL] = httputil.FileResponder(pudgyPic)
   144	
   145		return httputil.NewFakeTransport(responses)
   146	}
   147	
   148	// fakeCheckinsList returns a JSON checkins list of checkinsRequestLimit checkin
   149	// items, starting at offset. It stops before checkinsRequestLimit if maxCheckin is
   150	// reached. It uses towns to populate the venues. The returned list is saved in
   151	// cached.
   152	func fakeCheckinsList(offset, maxCheckin int, towns map[int]*venueLocationItem, cached map[int]string) string {
   153		if cl, ok := cached[offset]; ok {
   154			return cl
   155		}
   156		max := offset + checkinsRequestLimit
   157		if max > maxCheckin {
   158			max = maxCheckin
   159		}
   160		var items []*checkinItem
   161		tzCounter := 0
   162		venueCounter := 0
   163		for i := offset; i < max; i++ {
   164			shout := fmt.Sprintf("fakeShout %d", i)
   165			item := &checkinItem{
   166				Id:    blob.RefFromString(shout).DigestPrefix(10),
   167				Shout: shout,
   168				With: []*user{
   169					{
   170						Id:        "123",
   171						FirstName: "Kate",
   172						LastName:  "Pek",
   173						Photo: photoItem{
   174							Prefix: "https://irs3.4sqi.net/img/user/",
   175							Suffix: "/13674-S2IUMHALCCJJUTQO.jpg",
   176						},
   177					},
   178				},
   179				CreatedAt:      time.Now().Unix(),
   180				TimeZoneOffset: tzCounter * 60,
   181				Venue:          fakeVenue(venueCounter, towns),
   182			}
   183			items = append(items, item)
   184			tzCounter++
   185			venueCounter++
   186			if tzCounter == 24 {
   187				tzCounter = 0
   188			}
   189			if venueCounter == 5 {
   190				venueCounter = 0
   191			}
   192		}
   193	
   194		response := struct {
   195			Checkins struct {
   196				Items []*checkinItem
   197			}
   198		}{
   199			Checkins: struct {
   200				Items []*checkinItem
   201			}{
   202				Items: items,
   203			},
   204		}
   205		list, err := json.MarshalIndent(checkinsList{Response: response}, "", "	")
   206		if err != nil {
   207			log.Fatalf("%v", err)
   208		}
   209		cached[offset] = string(list)
   210		return cached[offset]
   211	}
   212	
   213	func fakeVenue(counter int, towns map[int]*venueLocationItem) venueItem {
   214		prefix := "https://perkeep.org/"
   215		suffix := "/pic/pudgy.png"
   216		// TODO: add more.
   217		categories := []*venueCategory{
   218			{
   219				Primary: true,
   220				Name:    "town",
   221				Icon: &categoryIcon{
   222					Prefix: prefix,
   223					Suffix: suffix,
   224				},
   225			},
   226		}
   227	
   228		return venueItem{
   229			Id:         blob.RefFromString(towns[counter].City).DigestPrefix(10),
   230			Name:       towns[counter].City,
   231			Location:   towns[counter],
   232			Categories: categories,
   233		}
   234	}
   235	
   236	func fakePhotosList() string {
   237		items := []*photoItem{
   238			fakePhotoItem(),
   239		}
   240		response := struct {
   241			Photos struct {
   242				Items []*photoItem
   243			}
   244		}{
   245			Photos: struct {
   246				Items []*photoItem
   247			}{
   248				Items: items,
   249			},
   250		}
   251		list, err := json.MarshalIndent(photosList{Response: response}, "", "	")
   252		if err != nil {
   253			log.Fatalf("%v", err)
   254		}
   255		return string(list)
   256	}
   257	
   258	func fakePhotoItem() *photoItem {
   259		prefix := "https://perkeep.org/"
   260		suffix := "/pic/pudgy.png"
   261		return &photoItem{
   262			Id:     blob.RefFromString(prefix + suffix).DigestPrefix(10),
   263			Prefix: prefix,
   264			Suffix: suffix,
   265			Width:  704,
   266			Height: 186,
   267		}
   268	}
   269	
   270	// TODO(mpl): refactor with twitter
   271	func fakePhoto() string {
   272		camliDir, err := osutil.GoPackagePath("perkeep.org")
   273		if err == os.ErrNotExist {
   274			log.Fatal("Directory \"perkeep.org\" not found under GOPATH/src; are you not running with devcam?")
   275		}
   276		if err != nil {
   277			log.Fatalf("Error searching for \"perkeep.org\" under GOPATH: %v", err)
   278		}
   279		return filepath.Join(camliDir, filepath.FromSlash("clients/web/embed/glitch/npc_piggy__x1_walk_png_1354829432.png"))
   280	}
Website layout inspired by memcached.
Content by the authors.