@@ -8,6 +8,10 @@ import crypto from 'crypto';
88const __filename = fileURLToPath ( import . meta. url ) ;
99const __dirname = path . dirname ( __filename ) ;
1010
11+ // Command line arguments
12+ const args = process . argv . slice ( 2 ) ;
13+ const forceRebuild = args . includes ( '--force' ) || args . includes ( '-f' ) ;
14+
1115// Google Sheets URL - converts to CSV export
1216const GOOGLE_SHEET_ID = '1N8vuOaxZoHAhiLSN-WTOkeHmXe9BMQok64w1z4GwC-g' ; // TODO In future replace with env var. This is not a security issue, rather just a convenience for switching environments.
1317const CSV_URL = `https://docs.google.com/spreadsheets/d/${ GOOGLE_SHEET_ID } /export?format=csv` ;
@@ -16,6 +20,7 @@ const CSV_URL = `https://docs.google.com/spreadsheets/d/${GOOGLE_SHEET_ID}/expor
1620const OUTPUT_DIR = path . join ( __dirname , '..' , 'public' , 'fetched' , 'officers' ) ;
1721const OUTPUT_FILE = path . join ( OUTPUT_DIR , 'officers.json' ) ;
1822const IMAGES_DIR = OUTPUT_DIR ;
23+ const HASH_TRACKING_FILE = path . join ( OUTPUT_DIR , '.sheet-hash' ) ;
1924
2025// Ensure images directory exists
2126if ( ! fs . existsSync ( IMAGES_DIR ) ) {
@@ -34,6 +39,25 @@ async function fetchOfficersData() {
3439 const csvData = await response . text ( ) ;
3540 console . log ( 'CSV data fetched successfully' ) ;
3641
42+ // Create hash of the CSV data
43+ const currentHash = crypto . createHash ( 'sha256' ) . update ( csvData ) . digest ( 'hex' ) ;
44+ console . log ( `Current sheet hash: ${ currentHash . slice ( 0 , 8 ) } ...` ) ;
45+
46+ // Check if we have a previous hash
47+ const previousHash = getPreviousHash ( ) ;
48+
49+ if ( previousHash === currentHash && ! forceRebuild ) {
50+ console . log ( 'Sheet data unchanged - skipping rebuild' ) ;
51+ console . log ( 'Use --force or -f flag to force a rebuild' ) ;
52+ return ;
53+ }
54+
55+ if ( forceRebuild ) {
56+ console . log ( 'Force rebuild requested - proceeding regardless of hash' ) ;
57+ } else {
58+ console . log ( 'Sheet data has changed - proceeding with rebuild' ) ;
59+ }
60+
3761 // Parse CSV to JSON
3862 const jsonData = csvToJson ( csvData ) ;
3963
@@ -51,6 +75,10 @@ async function fetchOfficersData() {
5175 console . log ( `Officers data saved to ${ OUTPUT_FILE } ` ) ;
5276 console . log ( `Found ${ processedData . length } officers` ) ;
5377
78+ // Save the new hash
79+ saveCurrentHash ( currentHash ) ;
80+ console . log ( 'Hash tracking file updated' ) ;
81+
5482 } catch ( error ) {
5583 console . error ( 'Error fetching officers data:' , error ) ;
5684 process . exit ( 1 ) ;
@@ -212,5 +240,24 @@ function parseCSVRow(row) {
212240 return result ;
213241}
214242
243+ function getPreviousHash ( ) {
244+ try {
245+ if ( fs . existsSync ( HASH_TRACKING_FILE ) ) {
246+ return fs . readFileSync ( HASH_TRACKING_FILE , 'utf8' ) . trim ( ) ;
247+ }
248+ } catch ( error ) {
249+ console . warn ( 'Could not read hash tracking file:' , error . message ) ;
250+ }
251+ return null ;
252+ }
253+
254+ function saveCurrentHash ( hash ) {
255+ try {
256+ fs . writeFileSync ( HASH_TRACKING_FILE , hash ) ;
257+ } catch ( error ) {
258+ console . warn ( 'Could not save hash to tracking file:' , error . message ) ;
259+ }
260+ }
261+
215262// Run the script
216263fetchOfficersData ( ) ;
0 commit comments