From fd7c1cc14dddca7f5f763b41b6b964bfb4b69a7e Mon Sep 17 00:00:00 2001 From: Aaron Boodman Date: Fri, 21 Oct 2016 14:49:03 -0700 Subject: [PATCH] Make dropbox work with the photos sample (#2745) * dropbox/find-photos: encode auth token in photo URLs so they can work in UI. * Remove requirement for datePublished from photo-index Dropbox doesn't have a publish date * fix test * review comments * npm test --- samples/go/photo-index/main.go | 35 ++++++++++++------ samples/go/photo-index/main_test.go | 2 + samples/js/dropbox/find-photos/src/main.js | 43 ++++++++++++---------- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/samples/go/photo-index/main.go b/samples/go/photo-index/main.go index b0b194edfa..c17d78c579 100644 --- a/samples/go/photo-index/main.go +++ b/samples/go/photo-index/main.go @@ -6,6 +6,7 @@ package main import ( "fmt" + "math" "os" "path" "sync" @@ -77,20 +78,24 @@ func index() (win bool) { "h": types.NumberType, }) photoType := types.MakeStructTypeFromFields("Photo", types.FieldMap{ - "sizes": types.MakeMapType(sizeType, types.StringType), - "title": types.StringType, - "datePublished": dateType, - "dateUpdated": dateType, + "id": types.StringType, + "sizes": types.MakeMapType(sizeType, types.StringType), }) withTags := types.MakeStructTypeFromFields("", types.FieldMap{ "tags": types.MakeSetType(types.StringType), }) + withFaces := types.MakeStructTypeFromFields("", types.FieldMap{ + "faces": types.MakeSetType(faceType), + }) withDateTaken := types.MakeStructTypeFromFields("", types.FieldMap{ "dateTaken": dateType, }) - withFaces := types.MakeStructTypeFromFields("", types.FieldMap{ - "faces": types.MakeSetType(faceType), + withDatePublished := types.MakeStructTypeFromFields("", types.FieldMap{ + "datePublished": dateType, + }) + withDateUpdated := types.MakeStructTypeFromFields("", types.FieldMap{ + "dateUpdated": dateType, }) byDate := types.NewGraphBuilder(db, types.MapKind, true) @@ -106,16 +111,22 @@ func index() (win bool) { if types.IsSubtype(photoType, cv.Type()) { s := cv.(types.Struct) - // Prefer to sort by the actual date the photo was taken, but if it's not - // available, use the date it was published instead. - ds := s.Get("datePublished") + // None of the date fields are required, but they are usually available. + var ds types.Value if types.IsSubtype(withDateTaken, cv.Type()) { ds = s.Get("dateTaken") + } else if types.IsSubtype(withDatePublished, cv.Type()) { + ds = s.Get("datePublished") + } else if types.IsSubtype(withDateUpdated, cv.Type()) { + ds = s.Get("dateUpdated") } - // Sort by most recent by negating the timestamp. - d := ds.(types.Struct).Get("nsSinceEpoch").(types.Number) - d = types.Number(-float64(d)) + d := types.Number(float64(math.MaxFloat64)) + if ds != nil { + // Sort by most recent by negating the timestamp. + d = ds.(types.Struct).Get("nsSinceEpoch").(types.Number) + d = types.Number(-float64(d)) + } // Index by date byDate.SetInsert([]types.Value{d}, cv) diff --git a/samples/go/photo-index/main_test.go b/samples/go/photo-index/main_test.go index 311b24016d..dd3f9295aa 100644 --- a/samples/go/photo-index/main_test.go +++ b/samples/go/photo-index/main_test.go @@ -37,6 +37,7 @@ func (s *testSuite) TestWin() { } type Photo struct { + Id string Title string Tags types.Set Faces types.Set @@ -72,6 +73,7 @@ func (s *testSuite) TestWin() { getPhoto := func(n int) Photo { return Photo{ + Id: fmt.Sprintf("photo%d", n), Title: fmt.Sprintf("photo %d", n), Tags: getTags(n), Sizes: map[struct{ Width, Height int }]string{ diff --git a/samples/js/dropbox/find-photos/src/main.js b/samples/js/dropbox/find-photos/src/main.js index 8a1ce45727..dec1fcd452 100644 --- a/samples/js/dropbox/find-photos/src/main.js +++ b/samples/js/dropbox/find-photos/src/main.js @@ -23,11 +23,14 @@ import { const args = argv .usage( - 'Indexes Photo objects out of slurped Dropbox metadata.\n\n' + - 'Note that the created objects have download URLs that are ' + - 'authenticated by Dropbox. You can request them like:\n\n' + - 'curl -H \'Authorization: Bearer \' \n\n' + - 'Usage: node . ') + 'Indexes Photo objects out of slurped Dropbox metadata.\n' + + 'See dropbox/slurp for how to get an access token.\n\n' + + 'Usage: node . --access-token= ') + .option('access-token', { + describe: 'Dropbox oauth access token', + type: 'string', + demand: true, + }) .demand(2) .argv; @@ -131,34 +134,34 @@ function getSizes(input: Object): Map { if (resized.scale > 1) { return null; } - - const args = { - path: input.id, - format: 'jpeg', - size: `w${width}h${height}`, - }; - const url = `${contentHost}files/get_thumbnail?arg=` + - encodeURIComponent(JSON.stringify(args)); - return [newStruct('', {width: resized.width, height: resized.height}), url]; + return [ + newStruct('', {width: resized.width, height: resized.height}), + getURL('files/get_thumbnail', { + path: input.id, + format: 'jpeg', + size: `w${width}h${height}`, + }), + ]; }); - const args = { - path: input.id, - }; - const url = `${contentHost}files/download?arg=` + - encodeURIComponent(JSON.stringify(args)); kv.push([ newStruct('', { width: orig.width, height: orig.height, }), - url, + getURL('files/download', {path: input.id}), ]); // $FlowIssue: Does not understand that filter removes all null values. return new Map(kv.filter(kv => kv)); } +function getURL(path: string, dbArgs: Object): string { + const dbArgStr = encodeURIComponent(JSON.stringify(dbArgs)); + return `${contentHost}${path}?arg=${dbArgStr}&` + + `authorization=Bearer%20${args['access-token']}`; +} + function newDate(iso: string): Struct { return newStruct('Date', { nsSinceEpoch: new Date(Date.parse(iso)).getTime() * nanosPerMilli,