Skip to content

Commit

Permalink
0.4.1 Hotfix Update
Browse files Browse the repository at this point in the history
---

- Fixed bug causing incorrect cwd to be set.
- Enhanced app logging.
- Changed `PyLoadBar` dependency version to 0.1.0
- Changed all `PyLoadBar` use cases to conform to new version params.
- Additions to docstrings.
- Added comments to source code.

Signed-off-by: schlopp96 <[email protected]>
  • Loading branch information
schlopp96 committed Jul 18, 2022
1 parent 69cdfe6 commit ccb5a24
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 60 deletions.
41 changes: 28 additions & 13 deletions PyFiTransfer/appevents/GUI_loop.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,63 @@
from random import uniform
from time import sleep

from PyFiTransfer.appevents.events import events, exit_program, logger
from PyFiTransfer.appgui.gui import sg, window


def GUI_loop() -> None:
"""GUI program event loop.
"""Main GUI loop.
- Starts processing of window events.
---
:return: run GUI program.
:return: program window
:rtype: None
"""

while True:
event, vals = window.read()
event, vals = window.read() # Get events from GUI window

logger.info(f'{event} : {vals}')
logger.info(f'{event} : {vals}') # Log events

if event in [sg.WIN_CLOSED, 'Exit']:
if event in [sg.WIN_CLOSED, 'Exit']: # Exit events
break

if event == '-Transfer-':
if event == '-Transfer-': # Process Transfer button event

# No source directory entered
if len(vals['-SourceFolderInput-']) < 1:
sg.Popup('Make sure all fields are filled out!')
continue

# No target directory entered
if len(vals['-TargetFolderInput-']) < 1:
sg.Popup('Make sure all fields are filled out!')
continue

# No file extension entered
if len(vals['-FileExtensionInput-']) < 1:
sg.Popup('Make sure all fields are filled out!')
continue

# Start Transfer
transfer: int = events.transfer(vals['-SourceFolderInput-'],
vals['-TargetFolderInput-'],
vals['-FileExtensionInput-'],
gui=True)
if transfer > 0:
for _ in range(50):

if transfer > 0: # Enable progress bar
for _ in range(25):
window.refresh()
sleep(uniform(0.01, 0.25))
sleep(uniform(0.01, 0.2))
window['-ProgressBar-'].update(_ + 1)
print(f'Successfully transferred {transfer} files!\n')
window['-ProgressBar-'].update(0)

window.close()
print(f'Successfully transferred {transfer} files!\n'
) # Log success

window['-ProgressBar-'].update(0) # Reset progress bar

window.close() # Close window and return system resources

return exit_program.success()
return exit_program.success() # Return successful exit status
60 changes: 31 additions & 29 deletions PyFiTransfer/appevents/events.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
from os import PathLike
from os.path import dirname
from os import PathLike, chdir
from os import scandir as lsContents
from os.path import basename as base
from shutil import move
Expand All @@ -9,11 +10,14 @@
from PyFiTransfer.applogger.logger import _LogGenerator
from PyLoadBar import PyLoadBar

logger = _LogGenerator(name='transferlog', filename='transferlog')
chdir(dirname(dirname(__file__)))

loader = PyLoadBar()
txt_seq = PyLoadBar(bar_sequence=False)
bar_seq = PyLoadBar()

BORDER: str = '\n='.ljust(50, '=')
logger = _LogGenerator('transferlog', 'Program')

BORDER: str = '\n<='.ljust(50, '=') + '=>'


class FileTransfer:
Expand All @@ -33,7 +37,7 @@ class FileTransfer:
- :func:`__verify_dir(self, filepath: PathLike | str) -> bool`
- Verify if given filepath is a directory.
- :func:`transfer(self, src_dir: str | os.PathLike, target_dir: str | os.PathLike, file_ext: str | os.PathLike) -> bool`
- :func:`transfer(self, src_dir: str | PathLike, target_dir: str | PathLike, file_ext: str | PathLike) -> bool | int`
- Transfer files from source directory to target directory.
"""

Expand Down Expand Up @@ -78,54 +82,50 @@ def _verify_dir(self, filepath: PathLike | str) -> bool:
:param filepath: path to directory.
:type filepath: :class:`PathLike` | :class:`str`
:return: :bool:`True` if directory exists, :bool:`False` if not.
:return: `True` if directory exists, `False` if not.
:rtype: :class:`bool`
"""
try:
logger.info(
f'Verifying directory of given file location:\n>> "{filepath}"...'
)
if isdir(filepath):
loader.load(
f'\nVerifying file transfer destination:\n>> "{filepath}"',
"\nDirectory verified successfully!",
enable_display=False,
)
txt_seq.start(
f'Verifying file transfer destination: "{filepath}"',
"Directory verified successfully!",
iter_total=5,
txt_seq_speed=0.25)
logger.info(
f"Filepath \"{filepath}\" verified successfully!\n")
return True
else:
loader.load(
f'\nVerifying file transfer destination:\n>> "{filepath}"',
txt_seq.start(
f'Verifying file transfer destination: "{filepath}"',
f'>> ERROR:\n>> Directory: "{filepath}" could NOT be verified.',
enable_display=False,
)
iter_total=5,
txt_seq_speed=0.25)
logger.warning(
f'Directory: "{filepath}" could NOT be verified...\n')
return False
except (OSError, ValueError, TypeError, EOFError) as error:
logger.exception(
f"Something went wrong during directory verification...\n>> {error}"
)
logger.info(
f">> ERROR:\nSomething went wrong during directory verification...\n>> {error.__traceback__}"
)
return False

def transfer(self, src_dir: str | os.PathLike,
target_dir: str | os.PathLike, file_ext: str | os.PathLike,
gui: bool) -> bool | int:
def transfer(self, src_dir: str | PathLike, target_dir: str | PathLike,
file_ext: str | PathLike, gui: bool) -> bool | int:
"""Transfer files of a given extension from source directory to target destination.
---
:param src_dir: starting location of transfer
:type src_dir: :class:`str` | :class:`os.PathLike`
:type src_dir: :class:`str` | :class:`PathLike`
:param target_dir: file transfer destination
:type target_dir: :class:`str` | :class:`os.PathLike`
:type target_dir: :class:`str` | :class:`PathLike`
:param file_ext: extension of files to be transferred
:type file_ext: :class:`str` | :class:`os.PathLike`
:return: :bool:`True` if transfer was successful, :bool:`False` if not.
:type file_ext: :class:`str` | :class:`PathLike`
:return: if :param:`gui` is `True`, return number of files transferred, else return `True` or `False` depending if transfer was successful or not.
:rtype: :class:`bool` | :class:`int`
"""

Expand Down Expand Up @@ -161,12 +161,14 @@ def transfer(self, src_dir: str | os.PathLike,
)
return len(files)

loader.load(
bar_seq.start(
msg_loading=
f'> Transferring all files with extension ".{file_ext}" to:\n>> "{target_dir}"',
msg_complete=
f'> {len(files)} files successfully copied to new location:\n>> {files}',
time=len(files))
min_iter=0.01,
max_iter=0.2,
iter_total=len(files))

logger.info(
f'{len(files)} files successfully copied to new location:\n>> "{target_dir}"\n'
Expand All @@ -181,11 +183,11 @@ def transfer(self, src_dir: str | os.PathLike,
return False


def change_ext(path: str | os.PathLike, curext: str, newext: str) -> None:
def change_ext(path: str | PathLike, curext: str, newext: str) -> None:
"""Change extension of all files of a given type.
:param path: path to containing directory of files to be changed
:type path: :class:`str` | :class:`os.PathLike`
:type path: :class:`str` | :class:`PathLike`
:param curext: extension of files to be changed
:type curext: :class:`str`
:param newext: extension to change files to.
Expand Down
2 changes: 1 addition & 1 deletion PyFiTransfer/appgui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
button_color=('white', 'green'))
],
[
sg.ProgressBar(max_value=50,
sg.ProgressBar(max_value=25,
size=(30, 10),
orientation='horizontal',
key='-ProgressBar-',
Expand Down
36 changes: 24 additions & 12 deletions PyFiTransfer/applogger/logger.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from os import PathLike


class _LogGenerator():
Expand All @@ -17,11 +18,12 @@ class _LogGenerator():
NOTSET = 0

def __init__(self,
name: str = __name__,
filename: str = __name__,
log_file: str | PathLike,
logger_name: str = __name__,
msgfmt: str = '[%(asctime)s - %(levelname)s] : %(message)s',
datefmt: str = "%Y-%m-%d %H:%M:%S",
level: int = DEBUG):
level: int = DEBUG,
stream: bool = False) -> None:
"""Initialize logger instance.
- For the :param:`level` parameter, the level of logging can be any of the following:
Expand All @@ -40,28 +42,38 @@ def __init__(self,
---
:param name: assign specific name to logger, defaults to `__name__`.
:type name: :class:`str`, optional
:param log_file: File to which logger output is written
:type log_file: :class:`str`
:param logname: assign specific name to logger, defaults to `__name__`
:type logname: :class:`str`, optional
:param msgfmt: initialize log entry formatter either with a specified custom formatting, or the default formatting as described above, defaults to `'[%(asctime)s - %(levelname)s] : %(message)s'`
:type msgfmt: :class:`str`, optional
:param datefmt: set date formatting, defaults to `'%Y-%m-%d %H:%M:%S'`
:type datefmt: :class:`str`, optional
:param level: Set the logging level of this logger. Level must be an int or a str, defaults to `DEBUG` (10).
:param level: Set the logging level of this logger. Level must be an int or a str, defaults to `DEBUG` (10)
:type level: :class:`int`, optional
:param stream: If `True`, log to stdout, defaults to `False`
:type stream: :class:`bool`, optional
:return: program logging instance
:rtype: None
"""

self.name: str = name
self.filename: str = filename
log_file: str = f'./logs/{self.filename}.log'
self.logname: str = logger_name
self.log_file: str | PathLike = log_file
self.msgfmt: str = msgfmt
self.datefmt: str = datefmt
self.level: int = level
self.logger: logging.Logger = logging.getLogger(self.name)
self.logger: logging.Logger = logging.getLogger(self.logname)
self.formatter: logging.Formatter = logging.Formatter(msgfmt, datefmt)
self.fhandler: logging.FileHandler = logging.FileHandler(log_file)
self.fhandler: logging.FileHandler = logging.FileHandler(
f'./logs/{log_file}.log')
self.logger.addHandler(self.fhandler)
self.fhandler.setFormatter(self.formatter)
self.logger.setLevel(level)
self.stream = stream

if self.stream: # If stream is True, log to stderr
self.logger.addHandler(logging.StreamHandler())

def debug(self, msg: str) -> None:
"""Log :param:`msg` with severity `DEBUG`.
Expand Down Expand Up @@ -122,7 +134,7 @@ def exception(self, msg: str, exc_info=True) -> None:
:param msg: message to be logged
:type msg: :class:`str`
:param exc_info: include exception info, defaults to :bool:`True`
:param exc_info: include exception info, defaults to `True`
:type exc_info: :class:`bool`, optional
:return: create log entry with given context and include exception info.
:rtype: None
Expand Down
3 changes: 0 additions & 3 deletions PyFiTransfer/main.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
#!/usr/bin/env python3

import sys
from os import chdir
from os.path import dirname

sys.path.insert(0, dirname(
dirname(__file__))) # Ensure main module can be found by Python.

# > Set CWD:
chdir(dirname(__file__))

from PyFiTransfer.appevents.events import logger
from PyFiTransfer.appevents.GUI_loop import GUI_loop
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
PyLoadBar>=0.0.8
PyLoadBar>=0.1.0
PySimpleGUI>=4.60.1
setuptools>=58.1.0
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
reqs = pathlib.Path("requirements.txt").read_text()
setup(
name="PyFiTransfer",
version="0.4.0",
version="0.4.1",
description=
'Transfer files with specified extension-type from a starting directory to desired target directory.',
url='https://github.com/schlopp96/PyFiTransfer',
Expand Down

0 comments on commit ccb5a24

Please sign in to comment.