150 lines
5.7 KiB
Python
150 lines
5.7 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk
|
|
import os
|
|
|
|
from shared_libs.message import MessageDialog
|
|
from shared_libs.custom_file_dialog import CustomFileDialog
|
|
from pbp_app_config import Msg
|
|
|
|
|
|
class ScheduleJobDialog(tk.Toplevel):
|
|
def __init__(self, parent, backup_manager):
|
|
super().__init__(parent)
|
|
self.parent = parent
|
|
self.backup_manager = backup_manager
|
|
self.result = None
|
|
|
|
self.title(Msg.STR["add_job_title"])
|
|
self.geometry("500x400")
|
|
self.transient(parent)
|
|
self.grab_set()
|
|
|
|
self.backup_type = tk.StringVar(value="system")
|
|
self.destination = tk.StringVar()
|
|
self.user_sources = {
|
|
Msg.STR["cat_images"]: tk.BooleanVar(value=False),
|
|
Msg.STR["cat_documents"]: tk.BooleanVar(value=False),
|
|
Msg.STR["cat_music"]: tk.BooleanVar(value=False),
|
|
Msg.STR["cat_videos"]: tk.BooleanVar(value=False)
|
|
}
|
|
self.frequency = tk.StringVar(value="daily")
|
|
|
|
self._create_widgets()
|
|
|
|
self.protocol("WM_DELETE_WINDOW", self._on_cancel)
|
|
self.wait_window()
|
|
|
|
def _create_widgets(self):
|
|
main_frame = ttk.Frame(self, padding=10)
|
|
main_frame.pack(fill=tk.BOTH, expand=True)
|
|
|
|
# Backup Type
|
|
type_frame = ttk.LabelFrame(
|
|
main_frame, text=Msg.STR["backup_type"], padding=10)
|
|
type_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
ttk.Radiobutton(type_frame, text=Msg.STR["system_backup_menu"], variable=self.backup_type,
|
|
value="system", command=self._toggle_user_sources).pack(anchor=tk.W)
|
|
ttk.Radiobutton(type_frame, text=Msg.STR["user_backup_menu"], variable=self.backup_type,
|
|
value="user", command=self._toggle_user_sources).pack(anchor=tk.W)
|
|
|
|
# Destination
|
|
dest_frame = ttk.LabelFrame(
|
|
main_frame, text=Msg.STR["dest_folder"], padding=10)
|
|
dest_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
ttk.Entry(dest_frame, textvariable=self.destination, state="readonly",
|
|
width=50).pack(side=tk.LEFT, fill=tk.X, expand=True)
|
|
ttk.Button(dest_frame, text=Msg.STR["browse"], command=self._select_destination).pack(
|
|
side=tk.RIGHT)
|
|
|
|
# User Sources (initially hidden)
|
|
self.user_sources_frame = ttk.LabelFrame(
|
|
main_frame, text=Msg.STR["source_folders"], padding=10)
|
|
for name, var in self.user_sources.items():
|
|
ttk.Checkbutton(self.user_sources_frame, text=name,
|
|
variable=var).pack(anchor=tk.W)
|
|
self._toggle_user_sources() # Set initial visibility
|
|
|
|
# Frequency
|
|
freq_frame = ttk.LabelFrame(
|
|
main_frame, text=Msg.STR["frequency"], padding=10)
|
|
freq_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
ttk.Radiobutton(freq_frame, text=Msg.STR["freq_daily"],
|
|
variable=self.frequency, value="daily").pack(anchor=tk.W)
|
|
ttk.Radiobutton(freq_frame, text=Msg.STR["freq_weekly"],
|
|
variable=self.frequency, value="weekly").pack(anchor=tk.W)
|
|
ttk.Radiobutton(freq_frame, text=Msg.STR["freq_monthly"],
|
|
variable=self.frequency, value="monthly").pack(anchor=tk.W)
|
|
|
|
# Buttons
|
|
button_frame = ttk.Frame(main_frame)
|
|
button_frame.pack(pady=10)
|
|
ttk.Button(button_frame, text=Msg.STR["save"], command=self._on_save).pack(
|
|
side=tk.LEFT, padx=5)
|
|
ttk.Button(button_frame, text=Msg.STR["cancel"], command=self._on_cancel).pack(
|
|
side=tk.LEFT, padx=5)
|
|
|
|
def _toggle_user_sources(self):
|
|
if self.backup_type.get() == "user":
|
|
self.user_sources_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
else:
|
|
self.user_sources_frame.pack_forget()
|
|
|
|
def _select_destination(self):
|
|
dialog = CustomFileDialog(
|
|
self, mode="dir", title=Msg.STR["select_dest_folder_title"])
|
|
self.wait_window(dialog)
|
|
result = dialog.get_result()
|
|
if result:
|
|
self.destination.set(result)
|
|
|
|
def _on_save(self):
|
|
dest = self.destination.get()
|
|
if not dest:
|
|
MessageDialog(master=self, message_type="error",
|
|
title=Msg.STR["error"], text=Msg.STR["err_no_dest_folder"])
|
|
return
|
|
|
|
job_type = self.backup_type.get()
|
|
job_frequency = self.frequency.get()
|
|
job_sources = []
|
|
|
|
if job_type == "user":
|
|
job_sources = [name for name,
|
|
var in self.user_sources.items() if var.get()]
|
|
if not job_sources:
|
|
MessageDialog(master=self, message_type="error",
|
|
title=Msg.STR["error"], text=Msg.STR["err_no_source_folder"])
|
|
return
|
|
|
|
# Construct the CLI command
|
|
script_path = os.path.abspath(os.path.join(
|
|
os.path.dirname(__file__), "main_app.py"))
|
|
command = f"python3 {script_path} --backup-type {job_type} --destination \"{dest}\""
|
|
if job_type == "user":
|
|
command += f" --sources "
|
|
for s in job_sources:
|
|
command += f'\"{s}\" '
|
|
|
|
# Construct the cron job comment
|
|
comment = f"{self.backup_manager.app_tag}; type:{job_type}; freq:{job_frequency}; dest:{dest}"
|
|
if job_type == "user":
|
|
comment += f"; sources:{','.join(job_sources)}"
|
|
|
|
self.result = {
|
|
"command": command,
|
|
"comment": comment,
|
|
"type": job_type,
|
|
"frequency": job_frequency,
|
|
"destination": dest,
|
|
"sources": job_sources
|
|
}
|
|
self.destroy()
|
|
|
|
def _on_cancel(self):
|
|
self.result = None
|
|
self.destroy()
|
|
|
|
def show(self):
|
|
self.parent.wait_window(self)
|
|
return self.result
|