@@ -647,4 +647,144 @@ def load_readme():
647647 return jsonify ({"success" : False , "error" : str (e )})
648648
649649
650+ @app .route ("/rename-folders" , methods = ["POST" ])
651+ def rename_folders ():
652+ """Add suffix to selected folders"""
653+ try :
654+ data = request .get_json ()
655+ action = data .get ("action" )
656+ paths = data .get ("paths" , [])
657+ suffix = data .get ("suffix" , "" )
658+
659+ if not paths :
660+ return jsonify ({"success" : False , "error" : "No paths provided" })
661+
662+ if action != "add-suffix" :
663+ return jsonify ({"success" : False , "error" : "Invalid action" })
664+
665+ if not suffix :
666+ return jsonify ({"success" : False , "error" : "No suffix provided" })
667+
668+ successful_renames = []
669+ failed_renames = []
670+
671+ for relative_path in paths :
672+ try :
673+ # Get the full path
674+ old_path = LOG_BASE_DIR / relative_path
675+
676+ if not old_path .exists ():
677+ failed_renames .append (f"{ relative_path } : does not exist" )
678+ continue
679+
680+ # Create new path with suffix
681+ parent_dir = old_path .parent
682+ old_name = old_path .name
683+ new_name = f"{ old_name } .{ suffix } "
684+ new_path = parent_dir / new_name
685+
686+ # Check if target already exists
687+ if new_path .exists ():
688+ failed_renames .append (f"{ relative_path } : target already exists" )
689+ continue
690+
691+ # Perform the rename
692+ old_path .rename (new_path )
693+ successful_renames .append (f"{ relative_path } → { old_name } .{ suffix } " )
694+
695+ except Exception as e :
696+ failed_renames .append (f"{ relative_path } : { str (e )} " )
697+
698+ if failed_renames :
699+ error_msg = "Some renames failed:\n " + "\n " .join (failed_renames )
700+ if successful_renames :
701+ error_msg += "\n \n Successful renames:\n " + "\n " .join (successful_renames )
702+ return jsonify ({"success" : False , "error" : error_msg })
703+
704+ return jsonify (
705+ {
706+ "success" : True ,
707+ "message" : f"Successfully renamed { len (successful_renames )} folder(s)" ,
708+ "renamed" : successful_renames ,
709+ }
710+ )
711+
712+ except Exception as e :
713+ return jsonify ({"success" : False , "error" : str (e )})
714+
715+
716+ @app .route ("/move-to-subfolder" , methods = ["POST" ])
717+ def move_to_subfolder ():
718+ """Move selected folders to a new subfolder"""
719+ try :
720+ data = request .get_json ()
721+ paths = data .get ("paths" , [])
722+ subfolder_name = data .get ("subfolder" , "" )
723+
724+ if not paths :
725+ return jsonify ({"success" : False , "error" : "No paths provided" })
726+
727+ if not subfolder_name :
728+ return jsonify ({"success" : False , "error" : "No subfolder name provided" })
729+
730+ # Validate subfolder name (no path separators, etc.)
731+ if "/" in subfolder_name or "\\ " in subfolder_name or ".." in subfolder_name :
732+ return jsonify ({"success" : False , "error" : "Invalid subfolder name" })
733+
734+ successful_moves = []
735+ failed_moves = []
736+
737+ for relative_path in paths :
738+ try :
739+ # Get the full path
740+ old_path = LOG_BASE_DIR / relative_path
741+
742+ if not old_path .exists ():
743+ failed_moves .append (f"{ relative_path } : does not exist" )
744+ continue
745+
746+ # Determine where to create the subfolder
747+ parent_dir = old_path .parent
748+ subfolder_path = parent_dir / subfolder_name
749+
750+ # Create subfolder if it doesn't exist
751+ subfolder_path .mkdir (exist_ok = True )
752+
753+ # Create new path inside subfolder
754+ folder_name = old_path .name
755+ new_path = subfolder_path / folder_name
756+
757+ # Check if target already exists
758+ if new_path .exists ():
759+ failed_moves .append (f"{ relative_path } : target already exists in subfolder" )
760+ continue
761+
762+ # Perform the move
763+ old_path .rename (new_path )
764+
765+ # Calculate the new relative path for display
766+ new_relative_path = str (new_path .relative_to (LOG_BASE_DIR ))
767+ successful_moves .append (f"{ relative_path } → { new_relative_path } " )
768+
769+ except Exception as e :
770+ failed_moves .append (f"{ relative_path } : { str (e )} " )
771+
772+ if failed_moves :
773+ error_msg = "Some moves failed:\n " + "\n " .join (failed_moves )
774+ if successful_moves :
775+ error_msg += "\n \n Successful moves:\n " + "\n " .join (successful_moves )
776+ return jsonify ({"success" : False , "error" : error_msg })
777+
778+ return jsonify (
779+ {
780+ "success" : True ,
781+ "message" : f"Successfully moved { len (successful_moves )} folder(s) to subfolder '{ subfolder_name } '" ,
782+ "moved" : successful_moves ,
783+ }
784+ )
785+
786+ except Exception as e :
787+ return jsonify ({"success" : False , "error" : str (e )})
788+
789+
650790# Use run_viewer.py to launch the application
0 commit comments