Skip to content

Commit

Permalink
Merge pull request #1 from kamildzi/v0.9.3
Browse files Browse the repository at this point in the history
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
  • Loading branch information
kamildzi authored Apr 15, 2023
2 parents bf005bf + f8154c3 commit b41ae57
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 9 deletions.
7 changes: 6 additions & 1 deletion GeneralSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@

# If "log_method" is set to a "File", then this setting can be used to define custom log directory.
# Blank value ("") means that logs will be saved in application directory ("./SavedLogs").
"custom_log_dir_path": ""
"custom_log_dir_path": "",

# Allows to define number of days after which the logs will be deleted.
# Empty value "" means than the feature is disabled (EEsync will not delete any logs on its own).
# Note: for advanced logging control it is recommended to use a dedicated tool (like logrotate).
"remove_logs_older_than_days": "14"
}

sync_rsync = {
Expand Down
1 change: 1 addition & 0 deletions Src/Config/ConfigManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def search_config_entries(self):
"""
Search for the saved configurations.
"""
self.config_list.clear()
config_number = 0
for file_name in sorted(os.listdir(self.config_directory)):
if self.config_match_regex.match(file_name):
Expand Down
5 changes: 4 additions & 1 deletion Src/EESync.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


class EESync:
__version = '0.9.2'
__version = '0.9.3'

sync_service = SyncProvider()
crypt_service = CryptProvider()
Expand All @@ -34,6 +34,9 @@ def start(self):

self.interactive_user_menu()

print("Cleanup actions...")
Logger.cleanup()

Logger.log("EESync finished.")
print("EESync finished.")

Expand Down
38 changes: 36 additions & 2 deletions Src/IO/Logger.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from datetime import datetime
from os import getcwd
from glob import glob
from os import getcwd, stat, remove
from os.path import isdir, isfile
from time import mktime

import GeneralSettings

Expand All @@ -10,6 +12,7 @@ class Logger:
The logger class.
"""
__start_date = None
__start_time = None
__log_dir = None
__log_file_is_ready: bool = False

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

# set the log directory
default_logs_directory: str = getcwd() + "/SavedLogs"
Expand Down Expand Up @@ -121,3 +126,32 @@ def __init_log_file(cls):
with open(save_path, 'w'):
pass
cls.__log_file_is_ready = True

@classmethod
def cleanup(cls):
"""
Handle the cleanup actions.
"""
try:
remove_logs_older_than_days = int(GeneralSettings.logger["remove_logs_older_than_days"])
except ValueError:
remove_logs_older_than_days = 0

if remove_logs_older_than_days > 0:
# remove old logs
cls.log(f"Rotating logs older than {remove_logs_older_than_days} days")

files_for_deletion = []
list_of_log_files = glob(f"{cls.__log_dir}/*.log")
for log_file in list_of_log_files:
# count time
file_time = stat(log_file).st_mtime
time_diff = cls.__start_time - file_time
days_diff = time_diff / 60 / 60 / 24
# register files for deletion
if days_diff > remove_logs_older_than_days:
files_for_deletion.append(log_file)

cls.log(f"Processing list of files for deletion: {files_for_deletion}")
for file_to_delete in files_for_deletion:
remove(file_to_delete)
9 changes: 6 additions & 3 deletions Src/Service/CommandRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from sys import getdefaultencoding

import GeneralSettings
from Src.IO.UserInputConsole import UserInputConsole
from Src.IO.Logger import Logger
from Src.IO.UserInputConsole import UserInputConsole


class CommandRunner:
Expand Down Expand Up @@ -34,14 +34,16 @@ def __init__(self):

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

return command_result

Expand Down
6 changes: 4 additions & 2 deletions Src/Service/SyncProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def __exec_rsync(self, source_dir: str, target_dir: str, dry_run: bool):
Executes the rsync command.
:param source_dir: Source directory - what to copy?
:param target_dir: Target directory - where to save a copy?
: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)
: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)
"""

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

# run the command
rsync_result = self.os_exec(exec_command, confirmation_required=True, capture_output=False)
rsync_result = self.os_exec(exec_command, confirmation_required=True, capture_output=False,
continue_on_failure=True)

# save the report
self.gen_run_report(exec_command, rsync_result.stdout, rsync_result.stderr)
Expand Down

0 comments on commit b41ae57

Please sign in to comment.