pull/1/head
pinb 5 months ago
commit 2240204c5e

@ -0,0 +1,16 @@
import sys
from PyQt5.QtWidgets import QApplication
from main_window import MainWindow
from database import create_tables, delete_old_logs
if __name__ == '__main__':
create_tables()
delete_old_logs()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
# pyinstaller --onefile bunnysync.py --add-data "images/realrabbit.png;images" --add-data "images/realrabbit2.png;images" --icon=images/realrabbit.png --noconsole

@ -0,0 +1,87 @@
import sqlite3
from datetime import datetime, timedelta
DB_NAME = 'my_data.db'
def get_db_conn():
conn = sqlite3.connect(DB_NAME)
return conn
def create_tables():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS jobs (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
folder1 TEXT NOT NULL,
folder2 TEXT NOT NULL,
interval INTEGER NOT NULL
)''')
cursor.execute('''CREATE TABLE IF NOT EXISTS logs (
id INTEGER PRIMARY KEY,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
message TEXT NOT NULL
)''')
conn.commit()
conn.close()
def add_job_to_db(name, folder1, folder2, interval):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('INSERT INTO jobs (name, folder1, folder2, interval) VALUES (?, ?, ?, ?)', (name, folder1, folder2, interval))
conn.commit()
conn.close()
def get_jobs_from_db():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('SELECT * FROM jobs')
jobs = cursor.fetchall()
conn.close()
return [{'name': job[1], 'folder1': job[2], 'folder2': job[3], 'interval': job[4]} for job in jobs]
def update_job_in_db(old_name, new_name, folder1, folder2, interval):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('''
UPDATE jobs SET name = ?, folder1 = ?, folder2 = ?, interval = ? WHERE name = ?
''', (new_name, folder1, folder2, interval, old_name))
conn.commit()
conn.close()
def delete_job_from_db(name):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('DELETE FROM jobs WHERE name = ?', (name,))
cursor.execute(f"DROP TABLE IF EXISTS {name}")
conn.commit()
conn.close()
def add_log_to_db(message):
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute('INSERT INTO logs (message) VALUES (?)', (message,))
conn.commit()
conn.close()
def get_logs_from_db():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
# cursor.execute('SELECT * FROM logs')
cursor.execute('''
SELECT *
FROM logs
ORDER BY timestamp DESC
LIMIT 30
''')
logs = cursor.fetchall()
conn.close()
return [(log[1], log[2]) for log in logs]
def delete_old_logs():
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
one_month_ago = datetime.now() - timedelta(days=30)
cursor.execute('DELETE FROM logs WHERE timestamp < ?', (one_month_ago,))
conn.commit()
conn.close()

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

@ -0,0 +1,35 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSizePolicy
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
import sys, os
class InfoWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout()
self.setLayout(layout)
image_label = QLabel()
image_path = self.resource_path("images/realrabbit2.png")
pixmap = QPixmap(image_path)
scaled_pixmap = pixmap.scaled(400,500, Qt.KeepAspectRatio, Qt.SmoothTransformation)
image_label.setPixmap(scaled_pixmap)
image_label.setAlignment(Qt.AlignCenter)
layout.addWidget(image_label)
self.info_label = QLabel('''
This is \'Bunny Sync\' Application !\n
Thank you for using the app 🤗\n
App Version 1.0\n
Made by PINB\n
''')
self.info_label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.info_label)
def resource_path(self, relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)

@ -0,0 +1,75 @@
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QPushButton
from job_thread import JobThread
class JobItem(QWidget):
def __init__(self, name, folder1, folder2, interval):
super().__init__()
self.name = name
self.folder1 = folder1
self.folder2 = folder2
self.interval = interval
self.thread = JobThread(self)
self.setup_ui()
def setup_ui(self):
layout = QHBoxLayout()
self.setLayout(layout)
self.name_label = QLabel(self.name)
self.name_label.setObjectName('jobitem')
self.play_button = QPushButton("Play")
self.sync_button = QPushButton("Sync")
self.delete_button = QPushButton("Delete")
layout.addWidget(self.name_label)
layout.addWidget(self.play_button)
layout.addWidget(self.sync_button)
layout.addWidget(self.delete_button)
self.setup_connections()
def setup_connections(self):
self.play_button.clicked.connect(self.toggle_play)
self.sync_button.clicked.connect(self.run_sync)
self.thread.current_log.connect(self.update_log)
def toggle_play(self):
if self.thread.is_running:
self.thread.stop()
self.play_button.setText("Play")
self.play_button.setStyleSheet('''
QPushButton {
background-color: #558DED;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
}
QPushButton:hover {
background-color: #55ED86;
}
''')
else:
self.thread.start()
self.play_button.setText("Pause")
self.play_button.setStyleSheet('''
QPushButton {
background-color: #55ED86;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
}
QPushButton:hover {
background-color: #558DED;
}
''')
def run_sync(self):
if not self.thread.is_running:
self.thread.sync()
def update_log(self, msg, fg, bg):
self.window().add_log(msg, fg, bg)

@ -0,0 +1,171 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QListWidget, QListWidgetItem
from PyQt5.QtGui import QColor
from PyQt5.QtCore import Qt
from job_item import JobItem
from database import add_job_to_db, get_jobs_from_db, update_job_in_db, delete_job_from_db
class JobListWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
self.load_jobs_from_db()
def setup_ui(self):
layout = QVBoxLayout()
self.setLayout(layout)
job_info_widget = QWidget()
job_info_layout = QVBoxLayout()
job_info_widget.setLayout(job_info_layout)
name_layout = QHBoxLayout()
name_label = QLabel("Job Name:")
name_label.setFixedSize(150, 35)
name_label.setObjectName('jobset')
name_label.setAlignment(Qt.AlignCenter)
name_layout.addWidget(name_label)
self.job_name_edit = QLineEdit()
name_layout.addWidget(self.job_name_edit)
folder1_layout = QHBoxLayout()
folder1_label = QLabel("Folder 1:")
folder1_label.setFixedSize(150, 35)
folder1_label.setObjectName('jobset')
folder1_label.setAlignment(Qt.AlignCenter)
folder1_layout.addWidget(folder1_label)
self.folder1_edit = QLineEdit()
folder1_layout.addWidget(self.folder1_edit)
folder2_layout = QHBoxLayout()
folder2_label = QLabel("Folder 2:")
folder2_label.setFixedSize(150, 35)
folder2_label.setObjectName('jobset')
folder2_label.setAlignment(Qt.AlignCenter)
folder2_layout.addWidget(folder2_label)
self.folder2_edit = QLineEdit()
folder2_layout.addWidget(self.folder2_edit)
interval_layout = QHBoxLayout()
interval_label = QLabel("Interval:")
interval_label.setFixedSize(150, 35)
interval_label.setObjectName('jobset')
interval_label.setAlignment(Qt.AlignCenter)
interval_layout.addWidget(interval_label)
self.interval_edit = QLineEdit()
interval_layout.addWidget(self.interval_edit)
buttons_layout = QHBoxLayout()
self.new_button = QPushButton("New")
self.new_button.clicked.connect(self.new_job)
buttons_layout.addWidget(self.new_button)
self.add_apply_button = QPushButton("Add")
self.add_apply_button.clicked.connect(self.add_job)
buttons_layout.addWidget(self.add_apply_button)
self.apply_button = QPushButton("Apply")
self.apply_button.clicked.connect(self.apply_job)
buttons_layout.addWidget(self.apply_button)
job_info_layout.addLayout(name_layout)
job_info_layout.addLayout(folder1_layout)
job_info_layout.addLayout(folder2_layout)
job_info_layout.addLayout(interval_layout)
job_info_layout.addLayout(buttons_layout)
layout.addWidget(job_info_widget)
self.job_list = QListWidget()
self.job_list.itemClicked.connect(self.show_job_info)
layout.addWidget(self.job_list)
def new_job(self):
self.job_name_edit.clear()
self.folder1_edit.clear()
self.folder2_edit.clear()
self.interval_edit.clear()
self.window().add_log('Clicked \'New Job\' !', QColor('yellow'), QColor('green'))
def add_job(self):
name = self.job_name_edit.text()
folder1 = self.folder1_edit.text()
folder2 = self.folder2_edit.text()
interval = self.interval_edit.text()
if name and folder1 and folder2 and interval:
# Check if job name already exists
if name == 'jobs' or name == 'logs' or name == 'sqlite_sequence':
self.window().add_log(f"Job with name '{name}' can not create.", QColor('white'), QColor('red'))
return
if any(self.job_list.itemWidget(self.job_list.item(i)).name == name for i in range(self.job_list.count())):
self.window().add_log(f"Job with name '{name}' already exists.", QColor('white'), QColor('red'))
return
job_item = JobItem(name, folder1, folder2, int(interval))
list_item = QListWidgetItem(self.job_list)
list_item.setSizeHint(job_item.sizeHint())
self.job_list.addItem(list_item)
self.job_list.setItemWidget(list_item, job_item)
job_item.delete_button.clicked.connect(lambda checked, item=list_item: self.delete_job(item))
add_job_to_db(name, folder1, folder2, int(interval))
self.window().add_log(f'Clicked \'Add Job\' - ({job_item.name}) !', QColor('yellow'), QColor('green'))
def delete_job(self, list_item):
job_item = self.job_list.itemWidget(list_item)
if job_item.thread.is_running:
job_item.thread.stop()
self.job_list.takeItem(self.job_list.row(list_item))
delete_job_from_db(job_item.name)
self.window().add_log(f'Clicked \'delete Job\' - ({job_item.name}) !', QColor('red'), QColor('green'))
def show_job_info(self, item):
job_item = self.job_list.itemWidget(item)
self.job_name_edit.setText(job_item.name)
self.folder1_edit.setText(job_item.folder1)
self.folder2_edit.setText(job_item.folder2)
self.interval_edit.setText(str(job_item.interval))
def apply_job(self):
self.selected_items = self.job_list.selectedItems()
if self.selected_items:
job_item = self.job_list.itemWidget(self.selected_items[0])
old_name = job_item.name
new_name = self.job_name_edit.text()
folder1 = self.folder1_edit.text()
folder2 = self.folder2_edit.text()
interval = self.interval_edit.text()
if new_name and folder1 and folder2 and interval:
# Check if new job name already exists in other jobs
if old_name != new_name and any(self.job_list.itemWidget(self.job_list.item(i)).name == new_name for i in range(self.job_list.count())):
self.window().add_log(f"Job with name '{old_name}' already exists.", QColor('white'), QColor('red'))
return
# Update the job item
job_item.name = new_name
job_item.folder1 = folder1
job_item.folder2 = folder2
job_item.interval = int(interval)
job_item.name_label.setText(new_name)
# Update the database
update_job_in_db(old_name, new_name, folder1, folder2, int(interval))
self.window().add_log(f'Clicked \'Apply Job\' - ({job_item.name}) !', QColor('yellow'), QColor('green'))
def load_jobs_from_db(self):
jobs = get_jobs_from_db()
for job in jobs:
job_item = JobItem(job['name'], job['folder1'], job['folder2'], job['interval'])
list_item = QListWidgetItem(self.job_list)
list_item.setSizeHint(job_item.sizeHint())
self.job_list.addItem(list_item)
self.job_list.setItemWidget(list_item, job_item)
job_item.delete_button.clicked.connect(lambda checked, item=list_item: self.delete_job(item))

@ -0,0 +1,30 @@
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QColor
import time
from sync import FolderSynchronizer
class JobThread(QThread):
current_log = pyqtSignal(str, QColor, QColor)
def __init__(self, job_item):
super().__init__()
self.name = job_item.name
self.folder1 = job_item.folder1
self.folder2 = job_item.folder2
self.interval = job_item.interval
self.is_running = False
self.synchronizer = FolderSynchronizer(self.name, self.folder1, self.folder2, self.interval)
def run(self):
self.is_running = True
while self.is_running:
log = self.synchronizer.sync_folders()
self.current_log.emit(log, QColor("white"), QColor("green"))
time.sleep(self.interval)
def stop(self):
self.is_running = False
def sync(self):
log = self.synchronizer.sync_folders()
self.current_log.emit(log, QColor("yellow"), QColor("green"))

@ -0,0 +1,93 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QTextEdit, QPushButton
from PyQt5.QtGui import QTextCursor, QTextBlockFormat, QTextCharFormat, QColor
from database import add_log_to_db, get_logs_from_db
from datetime import datetime
class LogWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
self.load_logs_from_db()
def setup_ui(self):
layout = QVBoxLayout()
self.setLayout(layout)
self.log_text = QTextEdit()
self.log_text.setReadOnly(True)
layout.addWidget(self.log_text)
self.log_input = QLineEdit()
self.log_input.setPlaceholderText("Enter log message")
layout.addWidget(self.log_input)
buttons_layout = QHBoxLayout()
log_button = QPushButton("Add Log")
log_button.clicked.connect(self.add_uilog)
buttons_layout.addWidget(log_button)
clear_button = QPushButton("Clear Log")
clear_button.clicked.connect(self.clear_log)
buttons_layout.addWidget(clear_button)
buttons_widget = QWidget()
buttons_widget.setLayout(buttons_layout)
layout.addWidget(buttons_widget)
def get_line_count(self):
document = self.log_text.document()
return document.blockCount()
def delete_first_line(self):
cursor = self.log_text.textCursor()
cursor.movePosition(QTextCursor.Start)
cursor.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor)
cursor.removeSelectedText()
self.log_text.setTextCursor(cursor)
def delete_lines(self, n):
cursor = self.log_text.textCursor()
cursor.movePosition(QTextCursor.Start)
for _ in range(n):
if cursor.atEnd():
break
cursor.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor)
cursor.removeSelectedText()
self.log_text.setTextCursor(cursor)
def clear_log(self):
self.log_text.clear()
def update_log(self, message, foreground=QColor("black"), background=QColor("white")):
char_format = QTextCharFormat()
char_format.setForeground(foreground)
char_format.setBackground(background)
block_format = QTextBlockFormat()
block_format.setBackground(background)
self.log_text.moveCursor(QTextCursor.End)
cursor = self.log_text.textCursor()
cursor.insertBlock(block_format)
cursor.insertText(message, char_format)
self.log_text.setTextCursor(cursor)
def add_log(self, message, foreground=QColor("black"), background=QColor("white")):
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_message = f"[{timestamp}] {message}"
self.update_log(log_message, foreground, background)
add_log_to_db(message)
self.log_input.clear()
if 3000 < self.get_line_count():
self.delete_first_line()
def add_uilog(self):
message = self.log_input.text()
self.add_log(message)
def load_logs_from_db(self):
logs = get_logs_from_db()
for timestamp, message in logs:
log_message = f"[{timestamp}] {message}"
self.update_log(log_message, QColor("dark"), QColor("gray"))

@ -0,0 +1,129 @@
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QLabel
from PyQt5.QtGui import QColor, QIcon
from job_list_widget import JobListWidget
from log_widget import LogWidget
from info_widget import InfoWidget
import sys, os
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Bunny Sync Application")
self.setGeometry(100, 100, 800, 600)
image_path = self.resource_path("images/realrabbit.png")
self.setWindowIcon(QIcon(image_path))
self.setup_ui()
def resource_path(self, relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
def setup_ui(self):
main_widget = QWidget()
main_layout = QHBoxLayout()
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
left_panel = QWidget()
left_layout = QVBoxLayout()
left_panel.setLayout(left_layout)
left_panel.setObjectName('menu')
left_panel.setFixedWidth(80)
self.list_button = QPushButton("List")
self.log_button = QPushButton("Log")
self.info_button = QPushButton("Info")
left_layout.addWidget(self.list_button)
left_layout.addWidget(self.log_button)
left_layout.addWidget(self.info_button)
left_layout.addStretch()
self.right_panel = QWidget()
self.right_layout = QVBoxLayout()
self.right_panel.setLayout(self.right_layout)
main_layout.addWidget(left_panel)
main_layout.addWidget(self.right_panel)
self.job_list_widget = JobListWidget(self)
self.log_widget = LogWidget(self)
self.info_widget = InfoWidget(self)
self.right_layout.addWidget(self.job_list_widget)
self.right_layout.addWidget(self.log_widget)
self.right_layout.addWidget(self.info_widget)
self.list_button.clicked.connect(self.show_job_list)
self.log_button.clicked.connect(self.show_log)
self.info_button.clicked.connect(self.show_info)
self.setStyleSheet("""
QWidget {
background-color: #C8F0F0;
border-radius: 10px;
padding: 10px;
}
QTextEdit {
background-color: #ffffff;
color: #333333;
border-radius: 10px;
padding: 10px;
}
QLineEdit {
background-color: #56BFF0;
color: #333333;
border-radius: 10px;
padding: 10px;
}
QLabel {
color: #333333;
font-size: 14px;
}
QLabel#jobset {
font-size: 14px;
font-weight: bold;
}
QLabel#jobitem {
background-color: #ffffff;
font-size: 10px;
font-weight: bold;
}
QPushButton {
background-color: #558DED;
color: white;
border: none;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
}
QPushButton:hover {
background-color: #55ED86;
}
QListWidget {
background-color: #56BFF0;
}
QWidget#menu {
background-color: #55EDED;
}
""")
self.show_job_list()
def show_job_list(self):
self.job_list_widget.show()
self.log_widget.hide()
self.info_widget.hide()
def show_log(self):
self.job_list_widget.hide()
self.log_widget.show()
self.info_widget.hide()
def show_info(self):
self.job_list_widget.hide()
self.log_widget.hide()
self.info_widget.show()
def add_log(self, message, foreground=QColor("black"), background=QColor("white")):
self.log_widget.add_log(message, foreground, background)

Binary file not shown.

@ -0,0 +1,151 @@
import os
import shutil
import time
import datetime
import sqlite3
import threading
DB_NAME = 'my_data.db'
class FolderSynchronizer:
def __init__(self, name, folder1, folder2, interval):
self.name = name
self.folder1 = folder1
self.folder2 = folder2
self.interval = interval
self.local = threading.local()
self.create_table()
def get_connection(self):
if not hasattr(self.local, 'conn'):
self.local.conn = sqlite3.connect(DB_NAME)
return self.local.conn
def get_cursor(self):
return self.get_connection().cursor()
def create_table(self):
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute(f'''
CREATE TABLE IF NOT EXISTS {self.name} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
rel_dir TEXT,
file_name TEXT,
modified1 REAL,
exist1 INTEGER,
modified2 REAL,
exist2 INTEGER,
UNIQUE(rel_dir, file_name)
)
''')
conn.commit()
# def delete_job(self):
# conn = self.get_connection()
# cursor = conn.cursor()
# cursor.execute(f"DROP TABLE IF EXISTS {self.name}")
# conn.commit()
# print(f"Job '{self.name}' has been deleted.")
def update_db(self, rel_dir, file_name, modified1, exist1, modified2, exist2):
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute(f'''
INSERT OR REPLACE INTO {self.name}
(rel_dir, file_name, modified1, exist1, modified2, exist2)
VALUES (?, ?, ?, ?, ?, ?)
''', (rel_dir, file_name, modified1, exist1, modified2, exist2))
conn.commit()
def get_file_info(self, rel_dir, file_name):
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute(f'''
SELECT * FROM {self.name}
WHERE rel_dir = ? AND file_name = ?
''', (rel_dir, file_name))
return cursor.fetchone()
def sync_folders(self):
def sync_files(src_folder, dest_folder):
current_time = time.time()
total_sync = 0
count_sync = 0
for root, _, files in os.walk(src_folder):
for filename in files:
src_path = os.path.join(root, filename)
rel_dir = os.path.relpath(root, src_folder)
dest_path = os.path.join(dest_folder, rel_dir, filename)
total_sync += 1
src_modified = os.path.getmtime(src_path)
file_info = self.get_file_info(rel_dir, filename)
if not file_info:
# New file
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
shutil.copy2(src_path, dest_path)
count_sync += 1
dest_modified = current_time
modified1, exist1, modified2, exist2 = src_modified, 1, dest_modified, 1
else:
# Existing file
if src_modified > file_info[3] or not file_info[4]:
shutil.copy2(src_path, dest_path)
count_sync += 1
dest_modified = current_time
modified1, exist1, modified2, exist2 = src_modified, 1, dest_modified, 1
else:
modified1, exist1, modified2, exist2 = src_modified, 1, file_info[5], file_info[6]
self.update_db(rel_dir, filename, modified1, exist1, modified2, exist2)
return total_sync, count_sync
def check_deleted_files():
conn = self.get_connection()
cursor = conn.cursor()
current_time = time.time()
count_sync = 0
cursor.execute(f"SELECT rel_dir, file_name, modified1, exist1, modified2, exist2 FROM {self.name}")
for row in cursor.fetchall():
rel_dir, file_name, modified1, exist1, modified2, exist2 = row
path1 = os.path.join(self.folder1, rel_dir, file_name)
path2 = os.path.join(self.folder2, rel_dir, file_name)
if not os.path.exists(path1) and not os.path.exists(path2):
count_sync += 1
cursor.execute(f"DELETE FROM {self.name} WHERE rel_dir = ? AND file_name = ?", (rel_dir, file_name))
elif not os.path.exists(path1) and exist1:
modified1 = current_time
if modified1 > modified2:
count_sync += 1
os.remove(path2)
cursor.execute(f"DELETE FROM {self.name} WHERE rel_dir = ? AND file_name = ?", (rel_dir, file_name))
else:
self.update_db(rel_dir, file_name, modified1, 0, modified2, exist2)
elif not os.path.exists(path2) and exist2:
modified2 = current_time
if modified2 > modified1:
count_sync += 1
os.remove(path1)
cursor.execute(f"DELETE FROM {self.name} WHERE rel_dir = ? AND file_name = ?", (rel_dir, file_name))
else:
self.update_db(rel_dir, file_name, modified1, exist1, modified2, 0)
conn.commit()
return count_sync
total_sync1, count_sync1 = sync_files(self.folder1, self.folder2)
total_sync2, count_sync2 = sync_files(self.folder2, self.folder1)
count_sync3 = check_deleted_files()
total_sync = max(total_sync1, total_sync2)
count_sync = count_sync1 + count_sync2 + count_sync3
# now = datetime.datetime.now()
# formatted_datetime = now.strftime("[%Y-%m-%d %H:%M:%S]")
# return f"[{self.name}] \'{self.folder1} <-> {self.folder2}\' Sync completed! (sync count: {count_sync}, total files: {total_sync})"
return f"[{self.name}] Sync completed! (sync count: {count_sync}, total files: {total_sync})"
Loading…
Cancel
Save