0

私はgoogle node apiを使用しています。私は次のことをしようとしています:

  1. Google ドライブのスプレッドシートの内容を読み取る
  2. 一部のデータを解釈します ( node-csvを使用して csv をオブジェクトに変換します)
  3. 次に、新しいコンテンツを含むファイルをアップロードします

このすべてを実行する作業コードがあります。すぐに共有します。

問題は、Googleドライブでスプレッドシートファイルを作成したときにコードがGoogleドライブからしかスプレッドシートファイルを読み取れないことです。ファイルを更新すると、APIから読み取ることができません(Googleドライブ自体で動作します)。したがって、上記の手順が機能し、再度実行すると、更新されたファイルが「見つかりません」と表示されます。ファイルのIDをまったく変更していないことに注意してください。

これはいくつかのコードでdrive.files、Promise 関数をライブラリに追加するPromises Bluebird のcsv関数で処理されています。 promisifyAll()Async

function getDriveFile(drive, id){
  return drive.files.getAsync({ fileId: id })
    .spread(function(data, response){
      console.log(data)
      return data.exportLinks['text/csv']
    }).then(function(csvDownload){
      return request({
        "method":"GET",
        "url": csvDownload,
        "qs":{
          "exportFormat": "csv",
          "key": id,
          "gid": 0
        },
        "headers":{
          "Authorization": "Bearer " + drive._options.auth.credentials.access_token
        }
      }).spread(function(response, body){
        return body
      })
    })
}

function driveGetAndParse(drive, fileId, fileName){
  return getDriveFile(drive, fileId).then(function(file){
    if(file.match("<!DOCTYPE html>")) throw new Error(fileName + " is not found")
    debug("fetched google drive %s doc", fileName)
    return csv.parseAsync(file, {columns: true})
  })
}

driveGetAndParse(drive, docId, "My super special doc"),


// one function that updates the file if there's and ID else inserts
function upload(drive, item){
  if(item.title) debug("uploading file '%s' to google drive", item.title)
  var options = {
    addParents: uloadparent,
    newRevision: false,
    convert: true,
    media: {
      mimeType: 'text/csv',
      body: item.content,
    }
  }
  if(item.id) options.fileId = item.id
  if(item.title) options.resourcetitle = item.title
  if(options.fileId){
    return drive.files.updateAsync(options)
      .spread(function(data, response){
        return data
      })
  }else{
    return drive.files.insertAsync(options)
      .spread(function(data, response){
        return data
      })
  }
}

2 つのファイルの管理画面での唯一の実際の違いは、アップロードされたドキュメントに余分なセルがなく、アップロードされたコンテンツを含むセルだけであることです。

権限の問題だと思うなら、そうですか?Google ドライブでは動作しますが、API では動作しません。私も同じことを考えていました。

明確にするために、を使用してファイル情報を取得できますdrive.files.get。を使用してファイル自体をダウンロードできませんdata.exportLinks['text/csv']

アップロードの前後にファイルのメタデータ、読み取り可能なダウンロード可能ファイル、およびダウンロード不可能なファイルを取得しました。これら 2 つの応答の違いは次のとおりです。

これが私がアップロードしている方法の問題なのか、それともダウンロードしている方法の問題なのかはわかりません.

ダウンロード リンクがあり、Google ドライブにログインしてブラウザにドロップすると、ファイルを問題なくダウンロードできます。

試み:

  1. 既存options.media.mimeType = "application/vnd.google-apps.spreadsheet"のドキュメントをtext/csv.
  2. options.convert = false既存のドキュメントを変換していると考えて同じことを試しました。

アップデート:

Googleドライブを使用してファイルを元に戻すと、ファイルを再度読み取ることができます。進捗?ファイルの内容/API自体に何か問題があるのでしょうか?

コードの変更:

insert/関数を分割し、updateで交差させuploadます。

function insert(drive, item){
  debug("inserting google drive file")
  return drive.files.insertAsync({
    addParents: uloadparent,
    newRevision: false,
    convert: true,
    media: {
      mimeType: 'text/csv',
      body: item.content,
    }
  }).spread(function(data, response){
    return data
  })
}

function update(drive, item){
  debug("updating google drive file")
  return drive.files.updateAsync({
    fileId: item.id,
    addParents: uloadparent,
    newRevision: false,
    convert: true,
    media: {
      mimeType: 'text/csv',
      body: item.content,
    }
  }).spread(function(data, response){
    return data
  })
}

function upload(drive, item){
  if(item.title) debug("uploading %s", item.title)
  if(item.id) return update(drive, item)
  return insert(drive, item)
}
4

1 に答える 1

0

自分で URL を作成していたときから、不要なクエリ パラメータがありました。

私は削除しました

  "qs":{
      "exportFormat": "csv",
      "key": id,
      "gid": 0
    },

ダウンロードスクリプトから、それは機能しました:)

于 2015-03-26T15:58:38.697 に答える