@@ -88,15 +88,9 @@ def rebuild_toc(toc_out: str = '') -> Tuple[bool, str]:
88
88
if not toc_out :
89
89
toc_out = toc_in
90
90
91
- # Open the output file for writing (overwriting any existing content)
92
- try :
93
- ofile = open (toc_out , 'w' , encoding = 'utf-8' )
94
- except :
95
- return (False , f"Failed to open '{ toc_out } ' for writing." )
96
-
97
- # Write a header for the TOC file
91
+ # Generate new TOC content
98
92
out = []
99
- out .append ("# ChatGPT System Prompts \n \n " )
93
+ out .append ("# ChatGPT System Prompts - Table of Contents \n \n " )
100
94
out .append ("This document contains a table of contents for the ChatGPT System Prompts repository.\n \n " )
101
95
102
96
# Add links to TOC.md files in prompts directory subdirectories
@@ -112,17 +106,36 @@ def rebuild_toc(toc_out: str = '') -> Tuple[bool, str]:
112
106
113
107
if prompt_dirs :
114
108
out .append ("## Prompt Collections\n \n " )
115
- prompt_dirs .sort () # Sort alphabetically
109
+ prompt_dirs .sort (key = str . lower ) # Sort alphabetically case-insensitive
116
110
for dirname in prompt_dirs :
117
111
# Create a relative link to the subdirectory TOC file
118
112
link = f"./prompts/{ dirname } /{ TOC_FILENAME } "
119
113
out .append (f"- [{ dirname } Collection]({ link } )\n " )
120
114
121
- ofile .writelines (out )
122
- ofile .close ()
123
- msg = f"Generated TOC with Prompt Collections only."
115
+ # Combine into a single string
116
+ new_content = '' .join (out )
124
117
125
- return (True , msg )
118
+ # Check if the file exists and if its content matches the new content
119
+ if os .path .exists (toc_out ):
120
+ try :
121
+ with open (toc_out , 'r' , encoding = 'utf-8' ) as existing_file :
122
+ existing_content = existing_file .read ()
123
+ if existing_content == new_content :
124
+ msg = f"TOC content unchanged, skipping write to '{ toc_out } '"
125
+ print (msg )
126
+ return (True , msg )
127
+ except Exception as e :
128
+ print (f"Warning: Could not read existing TOC file: { str (e )} " )
129
+
130
+ # Content is different or file doesn't exist, write the new content
131
+ try :
132
+ with open (toc_out , 'w' , encoding = 'utf-8' ) as ofile :
133
+ ofile .write (new_content )
134
+ msg = f"Generated TOC with Prompt Collections only."
135
+ return (True , msg )
136
+ except Exception as e :
137
+ msg = f"Failed to write TOC file: { str (e )} "
138
+ return (False , msg )
126
139
127
140
def make_template (url , verbose = True ):
128
141
"""Creates an empty GPT template file from a ChatGPT URL"""
@@ -305,47 +318,67 @@ def generate_gpts_toc(dir_path):
305
318
A tuple (success, message) indicating success/failure and a descriptive message
306
319
"""
307
320
toc_path = os .path .join (dir_path , TOC_FILENAME )
321
+
322
+ # Generate new content
308
323
try :
309
- with open (toc_path , 'w' , encoding = 'utf-8' ) as toc_file :
310
- toc_file .write (f"# gpts \n \n " )
311
-
312
- # Count GPTs
313
- enumerated_gpts = list (enum_gpts ())
314
- nb_ok = sum (1 for ok , gpt in enumerated_gpts if ok and gpt .id ())
315
-
316
- toc_file .write (f"## GPTs ({ nb_ok } total)\n \n " )
317
-
318
- nb_ok = nb_total = 0
319
- gpts = []
320
- for ok , gpt in enumerated_gpts :
321
- nb_total += 1
322
- if ok :
323
- if gpt_id := gpt .id ():
324
- nb_ok += 1
325
- gpts .append ((gpt_id , gpt ))
326
- else :
327
- print (f"[!] No ID detected: { gpt .filename } " )
324
+ out = []
325
+ out .append (f"# gpts - Table of Contents\n \n " )
326
+
327
+ # Count GPTs
328
+ enumerated_gpts = list (enum_gpts ())
329
+ nb_ok = sum (1 for ok , gpt in enumerated_gpts if ok and gpt .id ())
330
+
331
+ out .append (f"## GPTs ({ nb_ok } total)\n \n " )
332
+
333
+ nb_ok = nb_total = 0
334
+ gpts = []
335
+ for ok , gpt in enumerated_gpts :
336
+ nb_total += 1
337
+ if ok :
338
+ if gpt_id := gpt .id ():
339
+ nb_ok += 1
340
+ gpts .append ((gpt_id , gpt ))
328
341
else :
329
- print (f"[!] { gpt } " )
330
-
331
- # Consistently sort the GPTs by title
332
- def gpts_sorter (key ):
333
- gpt_id , gpt = key
334
- version = f"{ gpt .get ('version' )} " if gpt .get ('version' ) else ''
335
- return f"{ gpt .get ('title' )} { version } (id: { gpt_id .id } ))"
336
- gpts .sort (key = gpts_sorter )
337
-
338
- for id , gpt in gpts :
339
- file_link = f"./{ quote (os .path .basename (gpt .filename ))} "
340
- version = f" { gpt .get ('version' )} " if gpt .get ('version' ) else ''
341
- toc_file .write (f"- [{ gpt .get ('title' )} { version } (id: { id .id } )]({ file_link } )\n " )
342
+ print (f"[!] No ID detected: { gpt .filename } " )
343
+ else :
344
+ print (f"[!] { gpt } " )
345
+
346
+ # Consistently sort the GPTs by title
347
+ def gpts_sorter (key ):
348
+ gpt_id , gpt = key
349
+ version = f"{ gpt .get ('version' )} " if gpt .get ('version' ) else ''
350
+ return f"{ gpt .get ('title' , '' ).lower ()} { version } (id: { gpt_id .id } ))" # Case-insensitive sort
351
+ gpts .sort (key = gpts_sorter )
352
+
353
+ for id , gpt in gpts :
354
+ file_link = f"./{ quote (os .path .basename (gpt .filename ))} "
355
+ version = f" { gpt .get ('version' )} " if gpt .get ('version' ) else ''
356
+ out .append (f"- [{ gpt .get ('title' )} { version } (id: { id .id } )]({ file_link } )\n " )
357
+
358
+ new_content = '' .join (out )
359
+
360
+ # Check if the file exists and if its content matches the new content
361
+ if os .path .exists (toc_path ):
362
+ try :
363
+ with open (toc_path , 'r' , encoding = 'utf-8' ) as existing_file :
364
+ existing_content = existing_file .read ()
365
+ if existing_content == new_content :
366
+ msg = f"TOC content unchanged for 'gpts', skipping write"
367
+ print (msg )
368
+ return (True , msg )
369
+ except Exception as e :
370
+ print (f"Warning: Could not read existing gpts TOC file: { str (e )} " )
371
+
372
+ # Content is different or file doesn't exist, write the new content
373
+ with open (toc_path , 'w' , encoding = 'utf-8' ) as toc_file :
374
+ toc_file .write (new_content )
342
375
343
376
return (True , f"Generated TOC.md for 'gpts' with { nb_ok } out of { nb_total } GPTs." )
344
377
except Exception as e :
345
378
return (False , f"Error generating TOC.md for 'gpts': { str (e )} " )
346
379
347
380
# Process each top-level directory under prompts/
348
- for dirname in sorted (all_dirs ): # Sort for consistent processing order
381
+ for dirname in sorted (all_dirs , key = str . lower ): # Sort for consistent processing order
349
382
dir_path = os .path .join (prompts_base_path , dirname )
350
383
if not os .path .isdir (dir_path ):
351
384
messages .append (f"Directory '{ dirname } ' does not exist, skipping" )
@@ -370,52 +403,72 @@ def gpts_sorter(key):
370
403
# Generate TOC.md for this directory
371
404
toc_path = os .path .join (dir_path , TOC_FILENAME )
372
405
try :
406
+ # Generate new content
407
+ out = []
408
+ out .append (f"# { dirname } - Table of Contents\n \n " )
409
+
410
+ # Group files by their subdirectory
411
+ files_by_dir = {}
412
+ for rel_dir_path , filename , title in md_files :
413
+ if rel_dir_path not in files_by_dir :
414
+ files_by_dir [rel_dir_path ] = []
415
+ files_by_dir [rel_dir_path ].append ((filename , title ))
416
+
417
+ # First list files in the root directory
418
+ if '' in files_by_dir :
419
+ root_files = files_by_dir ['' ]
420
+ root_files .sort (key = lambda x : x [1 ].lower ()) # Sort alphabetically by title, case-insensitive
421
+
422
+ for filename , title in root_files :
423
+ out .append (f"- [{ title } ](./{ quote (filename )} )\n " )
424
+
425
+ # Add a separator if we have subdirectories
426
+ if len (files_by_dir ) > 1 :
427
+ out .append ("\n " )
428
+
429
+ # Then list files in subdirectories
430
+ subdirs = [d for d in files_by_dir .keys () if d != '' ]
431
+ if subdirs :
432
+ out .append ("## Subdirectories\n \n " )
433
+
434
+ # Sort subdirectories alphabetically, case-insensitive
435
+ subdirs .sort (key = str .lower )
436
+
437
+ for subdir in subdirs :
438
+ # Write the subdirectory name as a heading
439
+ display_subdir = subdir .replace ('\\ ' , '/' ) # Ensure consistent path display
440
+ out .append (f"### { display_subdir } \n \n " )
441
+
442
+ # Sort files in this subdirectory alphabetically by title, case-insensitive
443
+ subdir_files = files_by_dir [subdir ]
444
+ subdir_files .sort (key = lambda x : x [1 ].lower ())
445
+
446
+ for filename , title in subdir_files :
447
+ # Create a link with the correct relative path to the file
448
+ # Use os.path.join for correct path construction then replace backslashes for display
449
+ link_path = os .path .join (subdir , filename ).replace ('\\ ' , '/' )
450
+ out .append (f"- [{ title } ](./{ quote (link_path )} )\n " )
451
+
452
+ out .append ("\n " )
453
+
454
+ new_content = '' .join (out )
455
+
456
+ # Check if the file exists and if its content matches the new content
457
+ if os .path .exists (toc_path ):
458
+ try :
459
+ with open (toc_path , 'r' , encoding = 'utf-8' ) as existing_file :
460
+ existing_content = existing_file .read ()
461
+ if existing_content == new_content :
462
+ msg = f"TOC content unchanged for '{ dirname } ', skipping write"
463
+ print (msg )
464
+ messages .append (msg )
465
+ continue # Skip to next directory
466
+ except Exception as e :
467
+ print (f"Warning: Could not read existing TOC file for '{ dirname } ': { str (e )} " )
468
+
469
+ # Content is different or file doesn't exist, write the new content
373
470
with open (toc_path , 'w' , encoding = 'utf-8' ) as toc_file :
374
- toc_file .write (f"# { dirname } \n \n " )
375
-
376
- # Group files by their subdirectory
377
- files_by_dir = {}
378
- for rel_dir_path , filename , title in md_files :
379
- if rel_dir_path not in files_by_dir :
380
- files_by_dir [rel_dir_path ] = []
381
- files_by_dir [rel_dir_path ].append ((filename , title ))
382
-
383
- # First list files in the root directory
384
- if '' in files_by_dir :
385
- root_files = files_by_dir ['' ]
386
- root_files .sort () # Sort alphabetically
387
-
388
- for filename , title in root_files :
389
- toc_file .write (f"- [{ title } ](./{ quote (filename )} )\n " )
390
-
391
- # Add a separator if we have subdirectories
392
- if len (files_by_dir ) > 1 :
393
- toc_file .write ("\n " )
394
-
395
- # Then list files in subdirectories
396
- subdirs = [d for d in files_by_dir .keys () if d != '' ]
397
- if subdirs :
398
- toc_file .write ("## Subdirectories\n \n " )
399
-
400
- # Sort subdirectories alphabetically
401
- subdirs .sort ()
402
-
403
- for subdir in subdirs :
404
- # Write the subdirectory name as a heading
405
- display_subdir = subdir .replace ('\\ ' , '/' ) # Ensure consistent path display
406
- toc_file .write (f"### { display_subdir } \n \n " )
407
-
408
- # Sort files in this subdirectory alphabetically
409
- subdir_files = files_by_dir [subdir ]
410
- subdir_files .sort ()
411
-
412
- for filename , title in subdir_files :
413
- # Create a link with the correct relative path to the file
414
- # Use os.path.join for correct path construction then replace backslashes for display
415
- link_path = os .path .join (subdir , filename ).replace ('\\ ' , '/' )
416
- toc_file .write (f"- [{ title } ](./{ quote (link_path )} )\n " )
417
-
418
- toc_file .write ("\n " )
471
+ toc_file .write (new_content )
419
472
420
473
messages .append (f"Generated TOC.md for '{ dirname } ' with { len (md_files )} total files" )
421
474
0 commit comments