Picasa npm模块无法正常工作

时间:2017-09-11 06:45:45

标签: node.js google-api picasa

我一直在使用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

0 个答案:

没有答案