大家好,
我正在尝试从Gmail获取tar.gz附件,提取文件并将其保存到Google云端硬盘。这是每日自动生成的报告,由于原始大小> 25mb而被压缩。
到目前为止,我已经知道了:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Setup");
var gmailLabels = sheet.getRange("B2:B2").getValue(); //I have my Gmail Label stored here
var driveFolder = sheet.getRange("B5:B5").getValue(); //I have my GDrive folder name stored here
// apply label filter, search only last 24hrs mail
var filter = "has:attachment label:" + gmailLabels + " after:" + Utilities.formatDate(new Date(new Date().getTime()-1*(24*60*60*1000)), "GMT", "yyyy/MM/dd");
var threads = GmailApp.search(filter, 0, 1); // check only 1 email at a time
var folder = DriveApp.getFoldersByName(driveFolder);
if (folder.hasNext()) {
folder = folder.next();
} else {
folder = DriveApp.createFolder(driveFolder);
}
var message = threads[0].getMessages()[0];
var desc = message.getSubject() + " #" + message.getId();
var att = message.getAttachments();
for (var z=0; z<att.length; z++) {
var attName = att[z].getName()
var attExt = attName.search('csv')
if (attExt > 0){ var fileType = "csv"; }
else {
var attExt = attName.search('tar.gz');
if (attExt > 0){ var fileType = "gzip"; }
else {
threads[x].addLabel(skipLabel);
continue;
}
}
// save the file to GDrive
try {
file = folder.createFile(att[z]);
file.setDescription(desc);
}
catch (e) {
Logger.log(e.toString());
}
// extract if gzip
if (fileType == 'gzip' ){
var ungzippedFile = Utilities.ungzip(file);
try {
gz_file = folder.createFile(ungzippedFile);
gz_file.setDescription(desc);
}
catch (e) {
Logger.log(e.toString());
}
}
}
一切正常,但在最后一步中,它仅解压缩了.gz文件并将.tar文件保存在云端硬盘中。接下来我该怎么办? .tar文件包含一个.csv文件,之后需要提取并处理。
我应该补充一点,我仅限于使用GAS。
任何帮助都表示赞赏。
答案 0 :(得分:4)
这个答案怎么样?不幸的是,在当前阶段,尚无方法可从Google Apps脚本中的tar文件中提取文件。但是幸运的是,我们可以从wiki of tar中检索tar数据的结构。我使用此结构数据通过Google Apps脚本实现了此方法。
在运行此脚本之前,请将tar文件的文件ID设置为run()
。然后,运行run()
。
function tarUnarchiver(blob) {
var mimeType = blob.getContentType();
if (!mimeType || !~mimeType.indexOf("application/x-tar")) {
throw new Error("Inputted blob is not mimeType of tar. mimeType of inputted blob is " + mimeType);
}
var baseChunkSize = 512;
var byte = blob.getBytes();
var res = [];
do {
var headers = [];
do {
var chunk = byte.splice(0, baseChunkSize);
var headerStruct = {
filePath: function(b) {
var r = [];
for (var i = b.length - 1; i >= 0; i--) {
if (b[i] != 0) {
r = b.slice(0, i + 1);
break;
}
}
return r;
}(chunk.slice(0, 100)),
fileSize: chunk.slice(124, 124 + 11),
fileType: Utilities.newBlob(chunk.slice(156, 156 + 1)).getDataAsString(),
};
Object.keys(headerStruct).forEach(function(e) {
var t = Utilities.newBlob(headerStruct[e]).getDataAsString();
if (e == "fileSize") t = parseInt(t, 8);
headerStruct[e] = t;
});
headers.push(headerStruct);
} while (headerStruct.fileType == "5");
var lastHeader = headers[headers.length - 1];
var filePath = lastHeader.filePath.split("/");
var blob = Utilities.newBlob(byte.splice(0, lastHeader.fileSize)).setName(filePath[filePath.length - 1]).setContentTypeFromExtension();
byte.splice(0, Math.ceil(lastHeader.fileSize / baseChunkSize) * baseChunkSize - lastHeader.fileSize);
res.push({fileInf: lastHeader, file: blob});
} while (byte[0] != 0);
return res;
}
// Following function is a sample script for using tarUnarchiver().
// Please modify this to your situation.
function run() {
// When you want to extract the files from .tar.gz file, please use the following script.
var id = "### file ID of .tar.gz file ###";
var gz = DriveApp.getFileById(id).getBlob().setContentTypeFromExtension();
var blob = Utilities.ungzip(gz).setContentTypeFromExtension();
// When you want to extract the files from .tar file, please use the following script.
var id = "### file ID of .tar file ###";
var blob = DriveApp.getFileById(id).getBlob().setContentType("application/x-tar");
// Extract files from a tar data.
var res = tarUnarchiver(blob);
// If you want to create the extracted files to Google Drive, please use the following script.
res.forEach(function(e) {
DriveApp.createFile(e.file);
});
// You can see the file information by below script.
Logger.log(res);
}
例如,如果此脚本用于您的脚本,该如何处理?使用以上脚本的tarUnarchiver()
。但是我不确定您如何使用此脚本。因此,请将此作为示例。
// extract if gzip
if (fileType == 'gzip' ){
var ungzippedFile = Utilities.ungzip(file);
try {
var blob = ungzippedFile.setContentType("application/x-tar"); // Added
tarUnarchiver(blob).forEach(function(e) {folder.createFile(e.file)}); // Added
}
catch (e) {
Logger.log(e.toString());
}
}
ungzippedFile
(tar数据)的blob放入我的脚本并运行tarUnarchiver()
。然后,将每个文件创建到该文件夹。tarUnarchiver()
的响应。您可以从响应中将其视为fileInf
的属性。使用此脚本时,存在以下限制。这些限制是由于Google的规范所致。
在我的环境中,我可以确认该脚本有效。但是,如果该脚本不起作用,我深表歉意。那时,您可以提供示例tar文件吗?我想检查一下并修改脚本。