Skip to content

Commit b41ae57

Browse files
authored
Merge pull request #1 from kamildzi/v0.9.3
New release - v0.9.3 - bugfix: cleaning config entries on re-running the menu - logger time format updated - accept non zero outputs from rsync - usuful for ignoring some non-fatal warnings throwed by rsync - option for auto-removing logs (X days) - minor code cleanups
2 parents bf005bf + f8154c3 commit b41ae57

File tree

6 files changed

+57
-9
lines changed

6 files changed

+57
-9
lines changed

GeneralSettings.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121

2222
# If "log_method" is set to a "File", then this setting can be used to define custom log directory.
2323
# Blank value ("") means that logs will be saved in application directory ("./SavedLogs").
24-
"custom_log_dir_path": ""
24+
"custom_log_dir_path": "",
25+
26+
# Allows to define number of days after which the logs will be deleted.
27+
# Empty value "" means than the feature is disabled (EEsync will not delete any logs on its own).
28+
# Note: for advanced logging control it is recommended to use a dedicated tool (like logrotate).
29+
"remove_logs_older_than_days": "14"
2530
}
2631

2732
sync_rsync = {

Src/Config/ConfigManager.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def search_config_entries(self):
4444
"""
4545
Search for the saved configurations.
4646
"""
47+
self.config_list.clear()
4748
config_number = 0
4849
for file_name in sorted(os.listdir(self.config_directory)):
4950
if self.config_match_regex.match(file_name):

Src/EESync.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
class EESync:
14-
__version = '0.9.2'
14+
__version = '0.9.3'
1515

1616
sync_service = SyncProvider()
1717
crypt_service = CryptProvider()
@@ -34,6 +34,9 @@ def start(self):
3434

3535
self.interactive_user_menu()
3636

37+
print("Cleanup actions...")
38+
Logger.cleanup()
39+
3740
Logger.log("EESync finished.")
3841
print("EESync finished.")
3942

Src/IO/Logger.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from datetime import datetime
2-
from os import getcwd
2+
from glob import glob
3+
from os import getcwd, stat, remove
34
from os.path import isdir, isfile
5+
from time import mktime
46

57
import GeneralSettings
68

@@ -10,6 +12,7 @@ class Logger:
1012
The logger class.
1113
"""
1214
__start_date = None
15+
__start_time = None
1316
__log_dir = None
1417
__log_file_is_ready: bool = False
1518

@@ -19,7 +22,9 @@ def init(cls):
1922
Initialize the logger object.
2023
"""
2124
# set the date
22-
cls.__start_date = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
25+
curr_datetime = datetime.now()
26+
cls.__start_date = curr_datetime.strftime("%Y-%m-%d_%H:%M:%S")
27+
cls.__start_time = mktime(curr_datetime.timetuple())
2328

2429
# set the log directory
2530
default_logs_directory: str = getcwd() + "/SavedLogs"
@@ -121,3 +126,32 @@ def __init_log_file(cls):
121126
with open(save_path, 'w'):
122127
pass
123128
cls.__log_file_is_ready = True
129+
130+
@classmethod
131+
def cleanup(cls):
132+
"""
133+
Handle the cleanup actions.
134+
"""
135+
try:
136+
remove_logs_older_than_days = int(GeneralSettings.logger["remove_logs_older_than_days"])
137+
except ValueError:
138+
remove_logs_older_than_days = 0
139+
140+
if remove_logs_older_than_days > 0:
141+
# remove old logs
142+
cls.log(f"Rotating logs older than {remove_logs_older_than_days} days")
143+
144+
files_for_deletion = []
145+
list_of_log_files = glob(f"{cls.__log_dir}/*.log")
146+
for log_file in list_of_log_files:
147+
# count time
148+
file_time = stat(log_file).st_mtime
149+
time_diff = cls.__start_time - file_time
150+
days_diff = time_diff / 60 / 60 / 24
151+
# register files for deletion
152+
if days_diff > remove_logs_older_than_days:
153+
files_for_deletion.append(log_file)
154+
155+
cls.log(f"Processing list of files for deletion: {files_for_deletion}")
156+
for file_to_delete in files_for_deletion:
157+
remove(file_to_delete)

Src/Service/CommandRunner.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from sys import getdefaultencoding
55

66
import GeneralSettings
7-
from Src.IO.UserInputConsole import UserInputConsole
87
from Src.IO.Logger import Logger
8+
from Src.IO.UserInputConsole import UserInputConsole
99

1010

1111
class CommandRunner:
@@ -34,14 +34,16 @@ def __init__(self):
3434

3535
@staticmethod
3636
def os_exec(command: list, confirmation_required: bool = False, silent: bool = False, capture_output: bool = True,
37-
logging_enabled: bool = True) -> subprocess.CompletedProcess:
37+
logging_enabled: bool = True, continue_on_failure: bool = False) -> subprocess.CompletedProcess:
3838
"""
3939
A runner method. Throws exception when returncode is not 0.
4040
:param command: Command and the parameters in the form of a list.
4141
:param confirmation_required: bool value, False by default. Decide if we should ask user for the confirmation.
4242
:param silent: bool value, False by default. Allows to suppress printing the binary name that gets executed.
4343
:param capture_output: bool value, True by default. Allows to control whether the command output is captured.
4444
:param logging_enabled: bool value, True by default. Allows to control whether the logging feature is enabled.
45+
:param continue_on_failure: bool value, False by default. Allows to continue normal execution on failures
46+
(allows to accept non-zero result codes).
4547
:return: CompletedProcess object.
4648
"""
4749
process_env = dict(environ)
@@ -76,7 +78,8 @@ def os_exec(command: list, confirmation_required: bool = False, silent: bool = F
7678
+ f"\nDetails: \nSTDOUT: {command_result.stdout}\nSTDERR: {command_result.stderr}\n")
7779
if logging_enabled:
7880
Logger.log(failed_msg)
79-
raise SystemExit(failed_msg)
81+
if not continue_on_failure:
82+
raise SystemExit(failed_msg)
8083

8184
return command_result
8285

Src/Service/SyncProvider.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ def __exec_rsync(self, source_dir: str, target_dir: str, dry_run: bool):
7575
Executes the rsync command.
7676
:param source_dir: Source directory - what to copy?
7777
:param target_dir: Target directory - where to save a copy?
78-
:param dry_run: Should we do a test run? True means that rsync will only list the changes (but will not do anything to the files)
78+
:param dry_run: Should we do a test run? True means that rsync will only list the changes
79+
(but will not do anything to the files)
7980
"""
8081

8182
# validate source and target directories
@@ -107,7 +108,8 @@ def __exec_rsync(self, source_dir: str, target_dir: str, dry_run: bool):
107108
exec_command: list = [self.binary_path] + rsync_base_params + [source_dir, target_dir]
108109

109110
# run the command
110-
rsync_result = self.os_exec(exec_command, confirmation_required=True, capture_output=False)
111+
rsync_result = self.os_exec(exec_command, confirmation_required=True, capture_output=False,
112+
continue_on_failure=True)
111113

112114
# save the report
113115
self.gen_run_report(exec_command, rsync_result.stdout, rsync_result.stderr)

0 commit comments

Comments
 (0)