Free Code for AI & Python Projects

Some scripts for automating functions

Automated Backup - saves a version history of your selected filetypes.

import os
import time
import shutil
import tkinter as tk
from tkinter import filedialog, messagebox
from datetime import datetime
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class FileMonitor(FileSystemEventHandler):
    def __init__(self, watch_dir, backup_dir, extensions, log_text):
        self.watch_dir = watch_dir
        self.backup_dir = backup_dir
        self.extensions = extensions if extensions else ['.py', '.bat']
        self.log_text = log_text
        
        os.makedirs(self.backup_dir, exist_ok=True)
        
        self.initial_backup()

    def log(self, message):
        self.log_text.insert(tk.END, message + '\n')
        self.log_text.see(tk.END)

    def initial_backup(self):
        self.log("Starting initial backup...")
        for root, _, files in os.walk(self.watch_dir):
            if self.backup_dir in root:
                continue  # Skip backup directory
            for file in files:
                if any(file.lower().endswith(ext) for ext in self.extensions):
                    self.create_backup(os.path.join(root, file))
        self.log("Initial backup complete.")

    def on_modified(self, event):
        if event.is_directory or event.src_path.endswith('.tmp') or self.backup_dir in event.src_path:
            return
        self.process_file(event.src_path)

    def on_created(self, event):
        if event.is_directory or event.src_path.endswith('.tmp') or self.backup_dir in event.src_path:
            return
        self.process_file(event.src_path)

    def process_file(self, filepath):
        if self.backup_dir in filepath:
            return
        if any(filepath.lower().endswith(ext) for ext in self.extensions):
            self.create_backup(filepath)
    
    def create_backup(self, filepath):
        try:
            relative_path = os.path.relpath(filepath, self.watch_dir)
            backup_subdir = os.path.join(self.backup_dir, os.path.dirname(relative_path))
            os.makedirs(backup_subdir, exist_ok=True)

            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename, ext = os.path.splitext(os.path.basename(filepath))
            backup_filename = f"{filename}_{timestamp}{ext}"
            backup_path = os.path.join(backup_subdir, backup_filename)

            shutil.copy2(filepath, backup_path)
            self.log(f"Backup created: {backup_path}")
        except Exception as e:
            self.log(f"Error backing up {filepath}: {str(e)}")

class BackupApp:
    def __init__(self, root):
        self.root = root
        self.root.title("File Backup System")
        self.root.geometry("500x400")
        self.root.configure(bg="#e0e0e0")
        
        self.frame_expanded = tk.Frame(root, padx=15, pady=15, bg="#ffffff", relief=tk.RIDGE, borderwidth=2)
        self.frame_expanded.pack(fill=tk.BOTH, expand=True)

        tk.Label(self.frame_expanded, text="Select Watch Directory:", font=("Arial", 10, "bold"), bg="#ffffff").pack(anchor="w", pady=(5, 0))
        self.watch_entry = tk.Entry(self.frame_expanded, width=50)
        self.watch_entry.pack(pady=2)
        tk.Button(self.frame_expanded, text="Browse", command=self.select_watch_dir, bg="#4CAF50", fg="white").pack(pady=2)

        tk.Label(self.frame_expanded, text="Select Backup Directory:", font=("Arial", 10, "bold"), bg="#ffffff").pack(anchor="w", pady=(5, 0))
        self.backup_entry = tk.Entry(self.frame_expanded, width=50)
        self.backup_entry.pack(pady=2)
        tk.Button(self.frame_expanded, text="Browse", command=self.select_backup_dir, bg="#4CAF50", fg="white").pack(pady=2)

        tk.Label(self.frame_expanded, text="File Extensions (default: .py, .bat):", font=("Arial", 10, "bold"), bg="#ffffff").pack(anchor="w", pady=(5, 0))
        self.ext_entry = tk.Entry(self.frame_expanded, width=50)
        self.ext_entry.insert(0, ".py,.bat")
        self.ext_entry.pack(pady=2)

        self.start_button = tk.Button(self.frame_expanded, text="Start Backup", command=self.start_monitoring, bg="#008CBA", fg="white", font=("Arial", 10, "bold"))
        self.start_button.pack(pady=10)

        self.frame_collapsed = tk.Frame(root, padx=10, pady=10, bg="#ffffff", relief=tk.RIDGE, borderwidth=2)
        self.log_text = tk.Text(self.frame_collapsed, height=10, width=60, bg="#f9f9f9", fg="black", wrap=tk.WORD, font=("Courier", 10))
        self.log_text.pack(pady=5, padx=5, fill=tk.BOTH, expand=True)

        self.stop_button = tk.Button(self.frame_collapsed, text="Stop Backup", command=self.stop_monitoring, bg="#D32F2F", fg="white", font=("Arial", 10, "bold"))
        self.stop_button.pack(pady=10)
        
        self.observer = None

    def select_watch_dir(self):
        directory = filedialog.askdirectory()
        if directory:
            self.watch_entry.delete(0, tk.END)
            self.watch_entry.insert(0, directory)
    
    def select_backup_dir(self):
        directory = filedialog.askdirectory()
        if directory:
            self.backup_entry.delete(0, tk.END)
            self.backup_entry.insert(0, directory)

    def start_monitoring(self):
        watch_dir = self.watch_entry.get()
        backup_dir = self.backup_entry.get()
        extensions = [ext.strip() for ext in self.ext_entry.get().split(',')]
        
        if not watch_dir or not backup_dir:
            messagebox.showerror("Error", "Please select both watch and backup directories.")
            return
        
        self.event_handler = FileMonitor(watch_dir, backup_dir, extensions, self.log_text)
        self.observer = Observer()
        self.observer.schedule(self.event_handler, watch_dir, recursive=True)
        self.observer.start()
        
        self.frame_expanded.pack_forget()
        self.frame_collapsed.pack(fill=tk.BOTH, expand=True)
        
        self.log_text.insert(tk.END, "Monitoring started...\n")

    def stop_monitoring(self):
        if self.observer:
            self.observer.stop()
            self.observer.join()
            self.observer = None
        
        self.frame_collapsed.pack_forget()
        self.frame_expanded.pack(fill=tk.BOTH, expand=True)
        
        self.log_text.insert(tk.END, "Monitoring stopped.\n")

if __name__ == "__main__":
    root = tk.Tk()
    app = BackupApp(root)
    root.mainloop()

Create .exe files from Python files

Last updated