我一直在使用picasa npm模块从我的帐户中获取谷歌照片。
const options={
maxResults : 10
}
picasa.getPhotos(accessToken, options, (error, photos))
它正在归还所有照片。但最近,它显示以下错误
{
"error":{
"stack":"TypeError: Cannot read property 'map' of undefined\n
at executeRequest (/home/toobler/gosite-
dashboard/node_modules/picasa/src/picasa.js:162:35)\n
at Request.request.(anonymous function).error [as _callback]
(/home/toobler/gosite-
dashboard/node_modules/picasa/src/executeRequest.js:22:7)\n at
Request.self.callback (/home/toobler/gosite-
dashboard/node_modules/request/request.js:188:22)\n at emitTwo
(events.js:106:13)\n at Request.emit (events.js:191:7)\n at
Request.<anonymous> (/home/toobler/gosite-
dashboard/node_modules/request/request.js:1171:10)\n at emitOne
(events.js:96:13)\n at Request.emit (events.js:188:7)\n at
IncomingMessage.<anonymous> (/home/toobler/gosite-
dashboard/node_modules/request/request.js:1091:12)\n at
IncomingMessage.g (events.js:292:16)\n at emitNone
(events.js:91:20)\n at IncomingMessage.emit (events.js:185:7)\n
at endReadableNT (_stream_readable.js:974:12)\n at
_combinedTickCallback (internal/process/next_tick.js:80:11)\n at
process._tickDomainCallback (internal/process/next_tick.js:128:9)",
"message":"Cannot read property 'map' of undefined"
}
}
如果我使用
picasa.getAlbums(accessToken, options, (error, photos))
它将返回所有相册。
另外,如果我在选项中指定了albumId,那么
const options={
maxResults : 10,
albumId : "<albumId>"
}
picasa.getPhotos(accessToken, options, (error, photos))
正在返回该特定相册中的照片。 但是,无论相册如何,我都想要所有照片。 我错过了什么?
以下是/ home / toobler / gosite- dashboard / node_modules / picasa / src / picasa.js的代码
'use strict'
const querystring = require('querystring')
const executeRequest = require('./executeRequest')
const GOOGLE_AUTH_ENDPOINT = 'https://accounts.google.com/o/oauth2/auth'
const GOOGLE_API_HOST = 'https://www.googleapis.com'
const GOOGLE_API_PATH = '/oauth2/v3/token'
const GOOGLE_API_PATH_NEW = '/oauth2/v4/token'
const PICASA_SCOPE = 'https://picasaweb.google.com/data'
const PICASA_API_FEED_PATH = '/feed/api/user/default'
const PICASA_API_ENTRY_PATH = '/entry/api/user/default'
const FETCH_AS_JSON = 'json'
function Picasa () {
this.executeRequest = executeRequest
}
Picasa.prototype.getPhotos = getPhotos
Picasa.prototype.postPhoto = postPhoto
Picasa.prototype.deletePhoto = deletePhoto
Picasa.prototype.getAlbums = getAlbums
Picasa.prototype.createAlbum = createAlbum
// Auth utilities
Picasa.prototype.getAuthURL = getAuthURL
Picasa.prototype.getAccessToken = getAccessToken
Picasa.prototype.renewAccessToken = renewAccessToken
function getAlbums (accessToken, options, callback) {
const accessTokenParams = {
alt : FETCH_AS_JSON,
access_token : accessToken
}
options = options || {}
const requestQuery = querystring.stringify(accessTokenParams)
const requestOptions = {
url : `${PICASA_SCOPE}${PICASA_API_FEED_PATH}?${requestQuery}`,
headers: {
'GData-Version': '2'
}
}
this.executeRequest('get', requestOptions, (error, body) => {
if (error) return callback(error)
const albums = body.feed.entry.map(
entry => parseEntry(entry, albumSchema)
)
callback(null, albums)
})
}
function deletePhoto (accessToken, albumId, photoId, callback) {
const requestQuery = querystring.stringify({
alt : FETCH_AS_JSON,
access_token : accessToken
})
const requestOptions = {
url : `${PICASA_SCOPE}${PICASA_API_ENTRY_PATH}/albumid/${albumId}/photoid/${photoId}?${requestQuery}`,
headers: {
'If-Match': '*'
}
}
this.executeRequest('del', requestOptions, callback)
}
function createAlbum (accessToken, albumData, callback) {
const requestQuery = querystring.stringify({
alt : FETCH_AS_JSON,
access_token : accessToken
})
const albumInfoAtom = `<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:media='http://search.yahoo.com/mrss/'
xmlns:gphoto='http://schemas.google.com/photos/2007'>
<title type='text'>${albumData.title}</title>
<summary type='text'>${albumData.summary}</summary>
<gphoto:access>private</gphoto:access>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/photos/2007#album'></category>
</entry>`
const requestOptions = {
url : `${PICASA_SCOPE}${PICASA_API_FEED_PATH}?${requestQuery}`,
body : albumInfoAtom,
headers : {'Content-Type': 'application/atom+xml'}
}
this.executeRequest('post', requestOptions, (error, body) => {
if (error) return callback(error)
const album = parseEntry(body.entry, albumSchema)
callback(error, album)
})
}
function postPhoto (accessToken, albumId, photoData, callback) {
const requestQuery = querystring.stringify({
alt : FETCH_AS_JSON,
access_token : accessToken
})
const photoInfoAtom = `<entry xmlns="http://www.w3.org/2005/Atom">
<title>${photoData.title}</title>
<summary>${photoData.summary}</summary>
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo"/>
</entry>`
const requestOptions = {
url : `${PICASA_SCOPE}${PICASA_API_FEED_PATH}/albumid/${albumId}?${requestQuery}`,
multipart : [
{'Content-Type' : 'application/atom+xml', body : photoInfoAtom},
{'Content-Type' : photoData.contentType, body : photoData.binary}
]
}
this.executeRequest('post', requestOptions, (error, body) => {
if (error) return callback(error)
const photo = parseEntry(body.entry, photoSchema)
callback(error, photo)
})
}
function getPhotos (accessToken, options, callback) {
const accessTokenParams = {
alt : FETCH_AS_JSON,
kind : 'photo',
access_token : accessToken
}
options = options || {}
if (options.maxResults) accessTokenParams['max-results'] = options.maxResults
const albumPart = options.albumId ? `/albumid/${options.albumId}` : ''
const requestQuery = querystring.stringify(accessTokenParams)
const requestOptions = {
url : `${PICASA_SCOPE}${PICASA_API_FEED_PATH}${albumPart}?${requestQuery}`,
headers: {
'GData-Version': '2'
}
}
this.executeRequest('get', requestOptions, (error, body) => {
if (error) return callback(error)
const photos = body.feed.entry.map(
entry => parseEntry(entry, photoSchema)
)
callback(null, photos)
})
}
const albumSchema = {
'gphoto$id' : 'id',
'gphoto$name' : 'name',
'gphoto$numphotos' : 'num_photos',
'published' : 'published',
'title' : 'title',
'summary' : 'summary',
'gphoto$location' : 'location',
'gphoto$nickname' : 'nickname'
}
const photoSchema = {
'gphoto$id' : 'id',
'gphoto$albumid' : 'album_id',
'gphoto$access' : 'access',
'gphoto$width' : 'width',
'gphoto$height' : 'height',
'gphoto$size' : 'size' ,
'gphoto$checksum' : 'checksum',
'gphoto$timestamp' : 'timestamp',
'gphoto$imageVersion' : 'image_version',
'gphoto$commentingEnabled' : 'commenting_enabled',
'gphoto$commentCount' : 'comment_count',
'content' : 'content',
'title' : 'title',
'summary' : 'summary'
}
function parseEntry (entry, schema) {
let photo = {}
Object.keys(schema).forEach(schemaKey => {
const key = schema[schemaKey]
if (key) {
const value = checkParam(entry[schemaKey]);
photo[key] = value;
}
})
return photo
}
function getAuthURL (config) {
const authenticationParams = {
access_type : 'offline',
scope : `${PICASA_SCOPE}`,
response_type : 'code',
client_id : config.clientId,
redirect_uri : config.redirectURI
}
const authenticationQuery = querystring.stringify(authenticationParams)
return `${GOOGLE_AUTH_ENDPOINT}?${authenticationQuery}`
}
function getAccessToken (config, code, callback) {
const accessTokenParams = {
grant_type : 'authorization_code',
code : code,
redirect_uri : config.redirectURI,
client_id : config.clientId,
client_secret : config.clientSecret
}
const requestQuery = querystring.stringify(accessTokenParams)
const options = {
url : `${GOOGLE_API_HOST}${GOOGLE_API_PATH}?${requestQuery}`
}
this.executeRequest('post', options, (error, body) => {
if (error) return callback(error)
callback(null, body.access_token, body.refresh_token)
})
}
function renewAccessToken (config, refresh_token, callback){
const refreshTokenParams = {
grant_type: 'refresh_token',
client_id: config.clientId,
client_secret: config.clientSecret,
refresh_token: refresh_token
}
const requestQuery = querystring.stringify(refreshTokenParams)
const options = {
url: `${GOOGLE_API_HOST}${GOOGLE_API_PATH_NEW}?${requestQuery}`
}
this.executeRequest('post', options, (error, body) => {
if (error) return callback(error)
callback(null, body.access_token)
})
}
function checkParam (param) {
if (param === undefined) return ''
else if (isValidType(param)) return param
else if (isValidType(param['$t'])) return param['$t']
else return param
}
function isValidType (value) {
return typeof value === 'string' || typeof value === 'number'
}
module.exports = Picasa