-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDrive.js
More file actions
165 lines (132 loc) · 4.7 KB
/
Drive.js
File metadata and controls
165 lines (132 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/**
* DRIVE MODULE: The Librarian
* Responsibility: Finding, fetching, and archiving files.
*/
function getLatestPDF() {
const folderName = "MET_Drop_Zone";
const folders = DriveApp.getFoldersByName(folderName);
if (!folders.hasNext()) return null;
const folder = folders.next();
const files = folder.getFilesByType(MimeType.PDF);
return files.hasNext() ? files.next() : null;
}
function archiveFile(file) {
const archiveFolderName = "MET_Archive";
let archiveFolder;
const folders = DriveApp.getFoldersByName(archiveFolderName);
if (folders.hasNext()) {
archiveFolder = folders.next();
} else {
// Create it if it doesn't exist
archiveFolder = DriveApp.createFolder(archiveFolderName);
}
file.moveTo(archiveFolder);
console.log(`Archived: ${file.getName()}`);
}
/**
* DRIVE MODULE: Batch Processor
* Processes PDFs based on folder state rather than just a counter.
*/
function processAllPDFs() {
const folder = DriveApp.getFoldersByName("MET_Drop_Zone").next();
const fileIterator = folder.getFilesByType(MimeType.PDF);
// 1. Initial State Check: Is the folder empty?
if (!fileIterator.hasNext()) {
SpreadsheetApp.getUi().alert("📁 Folder is empty. Nothing to process!");
return;
}
let workWasPerformed = false;
// 2. Process the Queue
while (fileIterator.hasNext()) {
const file = fileIterator.next();
console.log("Processing: " + file.getName());
const success = extractTransactionsFromFile(file);
if (success) {
archiveFile(file);
workWasPerformed = true;
}
}
// 3. Final Verification
if (workWasPerformed) {
SpreadsheetApp.getUi().alert("✅ Batch Complete: All files processed and archived.");
} else {
SpreadsheetApp.getUi().alert("⚠️ Files were found, but none were successfully processed. Check your API logs.");
}
}
/**
* Archives a processed file into the Archive folder
* nested inside the MET-Universal parent folder.
*/
function archiveFile(file) {
const parentName = "MET-Universal";
const archiveName = "MET_Archive";
// 1. Find the Parent Folder
const parentFolders = DriveApp.getFoldersByName(parentName);
let parentFolder;
if (parentFolders.hasNext()) {
parentFolder = parentFolders.next();
} else {
// If somehow the parent is gone, create it as a fallback
parentFolder = DriveApp.createFolder(parentName);
}
// 2. Find or Create the Archive folder INSIDE the parent
const archiveFolders = parentFolder.getFoldersByName(archiveName);
let archiveFolder;
if (archiveFolders.hasNext()) {
archiveFolder = archiveFolders.next();
} else {
// Crucial change: parentFolder.createFolder instead of DriveApp.createFolder
archiveFolder = parentFolder.createFolder(archiveName);
}
// 3. Move the file
file.moveTo(archiveFolder);
console.log(`Successfully archived ${file.getName()} to ${parentName}/${archiveName}`);
}
/**
* DRIVE MODULE: Search
* Finds a specific PDF file by name in the Drop Zone.
*/
function getSpecificPDF(fileName) {
const folderName = "MET_Drop_Zone";
const folders = DriveApp.getFoldersByName(folderName);
if (!folders.hasNext()) return null;
const folder = folders.next();
// We search for files with that exact name
const files = folder.getFilesByName(fileName);
return files.hasNext() ? files.next() : null;
}
/**
* DRIVE MODULE: PDF Pre-processor
*/
async function getTrimmedPDFBlob(file) {
try {
const blob = file.getBlob();
const pdf = PDFApp.setPDFBlob(blob);
// 1. Get metadata and log it to solve the mystery
const metadata = await pdf.getMetadata();
console.log("DEBUG: Raw Metadata Type:", typeof metadata);
console.log("DEBUG: Raw Metadata Content:", JSON.stringify(metadata));
// Support both object and string returns
const metaObj = (typeof metadata === 'string') ? JSON.parse(metadata) : metadata;
const pageCount = metaObj.pageCount || metaObj.numberOfPages || 0;
console.log(`DEBUG: Detected Page Count: ${pageCount}`);
let pagesToKeep = [];
// If it's 4 pages, we skip 1, 2, and 4. We keep page 3.
if (pageCount >= 3) {
for (let i = 3; i < pageCount; i++) {
pagesToKeep.push(i);
}
}
if (pagesToKeep.length > 0) {
console.log(`Trimming successful. Keeping pages: ${pagesToKeep.join(",")}`);
const exported = await pdf.exportPages(pagesToKeep);
return (exported && typeof exported.getBlob === 'function') ? exported.getBlob() : exported;
} else {
console.log(`No pages to trim for a ${pageCount}-page PDF. Using original.`);
return blob;
}
} catch (err) {
console.error("Trimming failed, using original: " + err);
return file.getBlob();
}
}