update
This commit is contained in:
parent
014a98ee43
commit
15d7215af1
18 changed files with 701 additions and 0 deletions
71
bash_task_formatter/README.md
Normal file
71
bash_task_formatter/README.md
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
# BASH CLI Formatter with Spinner
|
||||||
|
|
||||||
|
This repository contains two scripts, `task_formatter.sh` and `example_usage.sh`, that work together to execute tasks with a spinner and formatted output. The `task_formatter.sh` script provides functions for running tasks with a spinner, while the `example_usage.sh` script demonstrates how to use these functions by defining and executing a set of tasks.
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
### task_formatter.sh
|
||||||
|
|
||||||
|
This script contains functions for running tasks with a spinner and formatted output.
|
||||||
|
|
||||||
|
#### Functions
|
||||||
|
|
||||||
|
- `spinner(pid)`: Displays a spinner while a background task is running.
|
||||||
|
- `run_task(task_description, task_command)`: Executes a task with a spinner and captures its output.
|
||||||
|
- `run_all_tasks(tasks)`: Runs all tasks passed as arguments, using the `run_task` function.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
The `task_formatter.sh` script is designed to be sourced by another script, which can then call its functions to run tasks with formatted output.
|
||||||
|
|
||||||
|
### example_usage.sh
|
||||||
|
|
||||||
|
This script demonstrates how to use the functions provided by `task_formatter.sh` to run a set of tasks.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
|
||||||
|
1. Ensure both `task_formatter.sh` and `example_usage.sh` are executable:
|
||||||
|
```bash
|
||||||
|
chmod +x task_formatter.sh
|
||||||
|
chmod +x example_usage.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run the `example_usage.sh` script:
|
||||||
|
```bash
|
||||||
|
./example_usage.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example Tasks
|
||||||
|
|
||||||
|
The `example_usage.sh` script defines three example tasks:
|
||||||
|
|
||||||
|
- `Task 1`: Runs the `sample_task` function, which simulates a task running for 3 seconds.
|
||||||
|
- `Task 2`: Runs the `another_sample_task` function, which simulates a task running for 5 seconds and then returns an error.
|
||||||
|
- `Task 3`: Runs the `sleep 2` command, which simulates a task running for 2 seconds.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
1. The `example_usage.sh` script sources the `task_formatter.sh` script to gain access to its functions.
|
||||||
|
2. The `example_usage.sh` script defines a set of tasks in an array, with each task specified as a description and a command separated by a colon (`:`).
|
||||||
|
3. The `example_usage.sh` script calls the `run_all_tasks` function from `task_formatter.sh`, passing the tasks as arguments.
|
||||||
|
4. The `run_all_tasks` function iterates over the tasks, splits each task into a description and a command, and calls the `run_task` function for each task.
|
||||||
|
5. The `run_task` function executes the task with a spinner and captures its output, displaying the task's status when it completes.
|
||||||
|
|
||||||
|
## Spinner
|
||||||
|
The Spinner was adjusted from https://github.com/sindresorhus/cli-spinners
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
Task 1 Running [⠼] [✔] Task 1 Completed 3s
|
||||||
|
Task 2 Running [⠧] [✘] Task 2 Error 5s
|
||||||
|
|
||||||
|
Error output:
|
||||||
|
Another sample task running
|
||||||
|
|
||||||
|
Task 3 Running [⠹] [✔] Task 3 Completed 2s
|
BIN
bash_task_formatter/bashformatterexample.gif
Normal file
BIN
bash_task_formatter/bashformatterexample.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 356 KiB |
49
bash_task_formatter/example_usage.sh
Normal file
49
bash_task_formatter/example_usage.sh
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Source the formatter script
|
||||||
|
source ./task_formatter.sh
|
||||||
|
|
||||||
|
# Example function 1
|
||||||
|
example_function_1() {
|
||||||
|
echo -e "This is example function 1. $CHECK_MARK"
|
||||||
|
sleep 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Example function 2
|
||||||
|
example_function_2() {
|
||||||
|
echo "This is example function 2."
|
||||||
|
sleep 2
|
||||||
|
echo -e "Done $CHECK_MARK"
|
||||||
|
sleep 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Example function 3 with an error
|
||||||
|
example_function_3() {
|
||||||
|
echo -e "This is example function 3 and it will fail. $CROSS_MARK"
|
||||||
|
sleep 3
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ask_reconfigure() {
|
||||||
|
read -p "Question? (y/n): " choice
|
||||||
|
case "$choice" in
|
||||||
|
y|Y ) return 0;;
|
||||||
|
n|N ) return 1;;
|
||||||
|
* ) echo "Invalid choice."; ask_reconfigure;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Using the formatter to format the output of the example functions
|
||||||
|
print_header "Example Formatter" "https://github.com/pitterpatter22/TaskFormatter/blob/main/bash_task_formatter/example_new.sh"
|
||||||
|
format_output example_function_1 "Example Function 1"
|
||||||
|
format_output example_function_2 "Example Function 2"
|
||||||
|
format_output example_function_3 "Example Function 3"
|
||||||
|
format_output_with_input ask_reconfigure "Test Reconfiguring"
|
||||||
|
|
||||||
|
|
||||||
|
# Print final message
|
||||||
|
final_message "Example Formatter (Success Example) $CHECK_MARK" 0
|
||||||
|
final_message "Example Formatter (Failure Example) $CROSS_MARK" 1
|
||||||
|
|
||||||
|
# Exit with appropriate status
|
||||||
|
exit 0
|
122
bash_task_formatter/formatter_new.sh
Normal file
122
bash_task_formatter/formatter_new.sh
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Color variables
|
||||||
|
COLOR_RESET="\033[0m"
|
||||||
|
COLOR_BLUE="\033[1;34m"
|
||||||
|
COLOR_YELLOW="\033[1;33m"
|
||||||
|
COLOR_GREEN="\033[1;32m"
|
||||||
|
COLOR_RED="\033[1;31m"
|
||||||
|
|
||||||
|
# Symbols
|
||||||
|
CHECK_MARK="\033[1;32m✔\033[0m"
|
||||||
|
CROSS_MARK="\033[1;31m✘\033[0m"
|
||||||
|
|
||||||
|
# Function to print header with script name
|
||||||
|
print_header() {
|
||||||
|
local script_name=$1
|
||||||
|
echo -e "${COLOR_GREEN}"
|
||||||
|
echo " _____ _ _ _ "
|
||||||
|
echo " / ____| (_) | | | "
|
||||||
|
echo " | (___ _ __ ___ _| |_| |__ ___ ___ _ ____ _____ _ __ "
|
||||||
|
echo " \\___ \\| '_ \` _ \\| | __| '_ \\/ __|/ _ \\ '__\\ \\ / / _ \\ '__|"
|
||||||
|
echo " ____) | | | | | | | |_| | | \\__ \\ __/ | \\ V / __/ | "
|
||||||
|
echo " |_____/|_| |_| |_|_|\\__|_| |_|___/\\___|_| \\_/ \\___|_| "
|
||||||
|
echo -e "${COLOR_RESET}\n"
|
||||||
|
echo -e "${COLOR_GREEN}${script_name}${COLOR_RESET}\n\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to display a spinner
|
||||||
|
spinner() {
|
||||||
|
local pid=$1
|
||||||
|
local func_name=$2
|
||||||
|
local delay=0.1
|
||||||
|
local spinstr=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
||||||
|
local temp
|
||||||
|
|
||||||
|
# Hide cursor
|
||||||
|
tput civis
|
||||||
|
|
||||||
|
while kill -0 "$pid" 2>/dev/null; do
|
||||||
|
for temp in "${spinstr[@]}"; do
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_YELLOW}Status: Running... %s${COLOR_RESET}" "$func_name" "$temp"
|
||||||
|
sleep $delay
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# Show cursor
|
||||||
|
tput cnorm
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to handle cleanup on exit
|
||||||
|
cleanup() {
|
||||||
|
local exit_status=$?
|
||||||
|
tput cnorm
|
||||||
|
if [[ -f "$temp_file" ]]; then
|
||||||
|
rm -f "$temp_file"
|
||||||
|
fi
|
||||||
|
if [[ $exit_status -ne 0 ]]; then
|
||||||
|
printf "\n${COLOR_RED}Script interrupted or an error occurred${COLOR_RESET}\n"
|
||||||
|
fi
|
||||||
|
exit $exit_status
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set trap for cleanup on exit or interrupt
|
||||||
|
trap cleanup EXIT
|
||||||
|
trap 'exit 130' INT
|
||||||
|
|
||||||
|
# Function to format the output of another function
|
||||||
|
format_output() {
|
||||||
|
local func_name=$1
|
||||||
|
local display_name=${2:-$func_name}
|
||||||
|
temp_file=$(mktemp)
|
||||||
|
|
||||||
|
# Run the function in the background and capture its output
|
||||||
|
( $func_name >"$temp_file" 2>&1 ) &
|
||||||
|
local pid=$!
|
||||||
|
spinner $pid "$display_name"
|
||||||
|
wait $pid
|
||||||
|
local exit_status=$?
|
||||||
|
|
||||||
|
if [ $exit_status -eq 0 ]; then
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
else
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${COLOR_BLUE}Output:${COLOR_RESET}"
|
||||||
|
cat "$temp_file"
|
||||||
|
echo "" # Ensure a new line after the function output
|
||||||
|
rm -f "$temp_file"
|
||||||
|
return $exit_status
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to format the output of another function that requires user input
|
||||||
|
format_output_with_input() {
|
||||||
|
local func_name=$1
|
||||||
|
local display_name=${2:-$func_name}
|
||||||
|
temp_file=$(mktemp)
|
||||||
|
|
||||||
|
echo -e "${COLOR_BLUE}Function: $display_name${COLOR_RESET} - ${COLOR_YELLOW}Status: Running...${COLOR_RESET}"
|
||||||
|
|
||||||
|
# Run the function in the foreground to handle interactive input
|
||||||
|
$func_name 2>&1 | tee "$temp_file"
|
||||||
|
local exit_status=${PIPESTATUS[0]}
|
||||||
|
|
||||||
|
if [ $exit_status -eq 0 ]; then
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
else
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${COLOR_BLUE}Output:${COLOR_RESET}"
|
||||||
|
cat "$temp_file"
|
||||||
|
echo "" # Ensure a new line after the function output
|
||||||
|
rm -f "$temp_file"
|
||||||
|
return $exit_status
|
||||||
|
}
|
||||||
|
|
||||||
|
# Export the functions for use in other scripts
|
||||||
|
export -f print_header
|
||||||
|
export -f format_output
|
||||||
|
export -f format_output_with_input
|
||||||
|
export COLOR_RESET COLOR_BLUE COLOR_YELLOW COLOR_GREEN COLOR_RED CHECK_MARK CROSS_MARK
|
155
bash_task_formatter/task_formatter.sh
Normal file
155
bash_task_formatter/task_formatter.sh
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Color variables
|
||||||
|
COLOR_RESET="\033[0m"
|
||||||
|
COLOR_BLUE="\033[1;34m"
|
||||||
|
COLOR_YELLOW="\033[1;33m"
|
||||||
|
COLOR_GREEN="\033[1;32m"
|
||||||
|
COLOR_RED="\033[1;31m"
|
||||||
|
|
||||||
|
# Symbols
|
||||||
|
CHECK_MARK="\033[1;32m✔\033[0m"
|
||||||
|
CROSS_MARK="\033[1;31m✘\033[0m"
|
||||||
|
|
||||||
|
|
||||||
|
# Function to center text
|
||||||
|
center_text() {
|
||||||
|
local text="$1"
|
||||||
|
local colorless_text=$(echo -e "$text" | sed 's/\x1b\[[0-9;]*m//g')
|
||||||
|
local width=$(tput cols)
|
||||||
|
local text_length=${#colorless_text}
|
||||||
|
local padding=$(( (width - text_length) / 2 ))
|
||||||
|
printf "%${padding}s%s\n" "" "$text"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to print header with script name
|
||||||
|
print_header() {
|
||||||
|
local script_name=$1
|
||||||
|
local script_link=$2
|
||||||
|
clear
|
||||||
|
echo -e "${COLOR_GREEN}"
|
||||||
|
center_text " ______ _ ______ _ _ "
|
||||||
|
center_text "| ___ \ | | | ___| | | | | "
|
||||||
|
center_text "| |_/ / __ _ ___| |__ | |_ ___ _ __ _ __ ___ __ _| |_| |_ ___ _ __ "
|
||||||
|
center_text "| ___ \/ _\` / __| '_ \ | _/ _ \| '__| '_ \` _ \ / _\` | __| __/ _ \ '__|"
|
||||||
|
center_text "| |_/ / (_| \__ \ | | | | || (_) | | | | | | | | (_| | |_| || __/ | "
|
||||||
|
center_text "\____/ \__,_|___/_| |_| \_| \___/|_| |_| |_| |_|\__,_|\__|\__\___|_| "
|
||||||
|
center_text " "
|
||||||
|
echo -e "${COLOR_YELLOW}\n"
|
||||||
|
center_text "${script_name}"
|
||||||
|
echo -e "\n"
|
||||||
|
center_text "${script_link}"
|
||||||
|
echo -e "${COLOR_RESET}\n"
|
||||||
|
echo -e "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Function to display a spinner
|
||||||
|
spinner() {
|
||||||
|
local pid=$1
|
||||||
|
local func_name=$2
|
||||||
|
local delay=0.1
|
||||||
|
local spinstr=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
||||||
|
local temp
|
||||||
|
|
||||||
|
# Hide cursor
|
||||||
|
tput civis
|
||||||
|
|
||||||
|
while kill -0 "$pid" 2>/dev/null; do
|
||||||
|
for temp in "${spinstr[@]}"; do
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_YELLOW}Status: Running... %s${COLOR_RESET}" "$func_name" "$temp"
|
||||||
|
sleep $delay
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# Show cursor
|
||||||
|
tput cnorm
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to handle cleanup on exit
|
||||||
|
cleanup() {
|
||||||
|
local exit_status=$?
|
||||||
|
tput cnorm
|
||||||
|
if [[ -f "$temp_file" ]]; then
|
||||||
|
rm -f "$temp_file"
|
||||||
|
fi
|
||||||
|
if [[ $exit_status -ne 0 ]]; then
|
||||||
|
printf "\n${COLOR_RED}Script interrupted or an error occurred${COLOR_RESET}\n"
|
||||||
|
fi
|
||||||
|
exit $exit_status
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set trap for cleanup on exit or interrupt
|
||||||
|
trap cleanup EXIT
|
||||||
|
trap 'exit 130' INT
|
||||||
|
|
||||||
|
# Function to format the output of another function
|
||||||
|
format_output() {
|
||||||
|
local func_name=$1
|
||||||
|
local display_name=${2:-$func_name}
|
||||||
|
temp_file=$(mktemp)
|
||||||
|
|
||||||
|
# Run the function in the background and capture its output
|
||||||
|
( $func_name >"$temp_file" 2>&1 ) &
|
||||||
|
local pid=$!
|
||||||
|
spinner $pid "$display_name"
|
||||||
|
wait $pid
|
||||||
|
local exit_status=$?
|
||||||
|
|
||||||
|
if [ $exit_status -eq 0 ]; then
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
else
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${COLOR_BLUE}Output:${COLOR_RESET}"
|
||||||
|
cat "$temp_file"
|
||||||
|
echo "" # Ensure a new line after the function output
|
||||||
|
rm -f "$temp_file"
|
||||||
|
return $exit_status
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to format the output of another function that requires user input
|
||||||
|
format_output_with_input() {
|
||||||
|
local func_name=$1
|
||||||
|
local display_name=${2:-$func_name}
|
||||||
|
temp_file=$(mktemp)
|
||||||
|
|
||||||
|
echo -e "${COLOR_BLUE}Function: $display_name${COLOR_RESET} - ${COLOR_YELLOW}Status: Running...${COLOR_RESET}"
|
||||||
|
|
||||||
|
# Run the function in the foreground to handle interactive input
|
||||||
|
$func_name 2>&1 | tee "$temp_file"
|
||||||
|
local exit_status=${PIPESTATUS[0]}
|
||||||
|
|
||||||
|
if [ $exit_status -eq 0 ]; then
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_GREEN}Status: Finished ${CHECK_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
else
|
||||||
|
printf "\r${COLOR_BLUE}Function: %s${COLOR_RESET} - ${COLOR_RED}Status: Error ${CROSS_MARK}${COLOR_RESET} \n" "$display_name"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" # Ensure a new line after the function output
|
||||||
|
rm -f "$temp_file"
|
||||||
|
return $exit_status
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to print final message
|
||||||
|
final_message() {
|
||||||
|
local script_name=$1
|
||||||
|
local success=$2
|
||||||
|
if [ -z "$success" ]; then
|
||||||
|
success=1
|
||||||
|
fi
|
||||||
|
if [ "$success" -eq 0 ]; then
|
||||||
|
echo -e "\n${COLOR_GREEN}${script_name} completed successfully!${COLOR_RESET}\n"
|
||||||
|
else
|
||||||
|
echo -e "\n${COLOR_RED}${script_name} encountered errors!${COLOR_RESET}\n"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Export the functions for use in other scripts
|
||||||
|
export -f print_header
|
||||||
|
export -f format_output
|
||||||
|
export -f format_output_with_input
|
||||||
|
export -f final_message
|
||||||
|
export COLOR_RESET COLOR_BLUE COLOR_YELLOW COLOR_GREEN COLOR_RED CHECK_MARK CROSS_MARK
|
73
python_task_formatter/README.md
Normal file
73
python_task_formatter/README.md
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# Formatter and Example
|
||||||
|
|
||||||
|
This project demonstrates the use of a Python decorator to format the output of functions, showing a running spinner, and indicating success or failure with colored and formatted text. It includes two files: `formatter.py` and `example.py`.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
`pip install TaskFormatter`
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
1. **formatter.py**: This file contains the `format_output` decorator that provides the desired formatting for function output.
|
||||||
|
2. **example.py**: This file demonstrates how to use the `format_output` decorator by applying it to two example functions, one that succeeds and one that fails.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Spinner Animation**: Displays a spinner animation while the function is running.
|
||||||
|
- **Success/Failure Indication**: Shows a green checkmark for successful completion and a red cross for failures.
|
||||||
|
- **Exception Handling**: Exceptions are displayed in red and underlined.
|
||||||
|
- **Function Numbering**: Each function is prefixed with a unique number.
|
||||||
|
- **Text Formatting**: Function names are displayed in bold and underlined.
|
||||||
|
- **Separation of Outputs**: Outputs from different functions are separated by a line for clarity.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### 1. formatter.py
|
||||||
|
|
||||||
|
The `format_output` decorator is defined in this file. It wraps a function to display the running spinner, success/failure message, and handle exceptions.
|
||||||
|
|
||||||
|
### 2. example.py
|
||||||
|
|
||||||
|
The `example.py` file demonstrates the use of the `format_output` decorator. It includes two functions, one that succeeds and one that fails, to showcase the decorator's functionality.
|
||||||
|
|
||||||
|
```
|
||||||
|
from TaskFormatter import format_output
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
@format_output
|
||||||
|
def successful_function():
|
||||||
|
print("Starting")
|
||||||
|
sleep(2)
|
||||||
|
print("Function logic output")
|
||||||
|
|
||||||
|
@format_output
|
||||||
|
def failing_function():
|
||||||
|
print("Just Started")
|
||||||
|
sleep(2)
|
||||||
|
print("Running")
|
||||||
|
sleep(2)
|
||||||
|
print("Done")
|
||||||
|
raise ValueError("Custom Error")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
successful_function()
|
||||||
|
try:
|
||||||
|
failing_function()
|
||||||
|
except Exception as e:
|
||||||
|
print("Caught an exception: ", e)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running the Example
|
||||||
|
|
||||||
|
1. Save formatter.py and example.py in the same directory.
|
||||||
|
2. Run example.py using the command:
|
||||||
|
```
|
||||||
|
python example.py
|
||||||
|
```
|
||||||
|
You should see the spinner, success, and failure messages formatted as described, with appropriate separation and formatting for each function's output.
|
91
python_task_formatter/TaskFormatter/TaskFormatter.py
Normal file
91
python_task_formatter/TaskFormatter/TaskFormatter.py
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import multiprocessing
|
||||||
|
from functools import wraps
|
||||||
|
import signal
|
||||||
|
import io
|
||||||
|
|
||||||
|
# Global counter for function numbering
|
||||||
|
function_counter = multiprocessing.Value('i', 0)
|
||||||
|
|
||||||
|
def spinner(function_number, func_name, spinner_done, print_lock):
|
||||||
|
spinner_gen = spinner_gen_func()
|
||||||
|
while not spinner_done.is_set():
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[94m{function_number}. {func_name} Running [{next(spinner_gen)}] \033[0m")
|
||||||
|
sys.stdout.flush()
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
def spinner_gen_func():
|
||||||
|
while True:
|
||||||
|
for cursor in "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏":
|
||||||
|
yield cursor
|
||||||
|
|
||||||
|
def format_output(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
with function_counter.get_lock():
|
||||||
|
function_counter.value += 1
|
||||||
|
function_number = function_counter.value
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
func_name = func.__name__
|
||||||
|
spinner_done = multiprocessing.Event()
|
||||||
|
print_lock = multiprocessing.Lock()
|
||||||
|
|
||||||
|
spin_process = multiprocessing.Process(target=spinner, args=(function_number, func_name, spinner_done, print_lock))
|
||||||
|
spin_process.start()
|
||||||
|
|
||||||
|
def handle_exit(signum, frame):
|
||||||
|
raise SystemExit("Process exited")
|
||||||
|
|
||||||
|
signal.signal(signal.SIGTERM, handle_exit)
|
||||||
|
signal.signal(signal.SIGINT, handle_exit)
|
||||||
|
|
||||||
|
buffer = io.StringIO()
|
||||||
|
original_stdout = sys.stdout
|
||||||
|
sys.stdout = buffer
|
||||||
|
|
||||||
|
try:
|
||||||
|
func(*args, **kwargs)
|
||||||
|
duration = time.time() - start_time
|
||||||
|
spinner_done.set()
|
||||||
|
spin_process.join()
|
||||||
|
sys.stdout = original_stdout
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[92m{function_number}. {func_name} Completed [✓] in {duration:.2f}s\033[0m\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
output = buffer.getvalue().strip()
|
||||||
|
if output:
|
||||||
|
sys.stdout.write(output + "\n")
|
||||||
|
sys.stdout.write('\n---\n') # Add separator before the next function
|
||||||
|
except SystemExit as e:
|
||||||
|
duration = time.time() - start_time
|
||||||
|
spinner_done.set()
|
||||||
|
spin_process.join()
|
||||||
|
sys.stdout = original_stdout
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
output = buffer.getvalue().strip()
|
||||||
|
if output:
|
||||||
|
sys.stdout.write(output + "\n")
|
||||||
|
print(f"\033[91m\033[4m{e}\033[0m")
|
||||||
|
sys.stdout.write('\n---\n') # Add separator before the next function
|
||||||
|
raise e
|
||||||
|
except Exception as e:
|
||||||
|
duration = time.time() - start_time
|
||||||
|
spinner_done.set()
|
||||||
|
spin_process.join()
|
||||||
|
sys.stdout = original_stdout
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
output = buffer.getvalue().strip()
|
||||||
|
if output:
|
||||||
|
sys.stdout.write(output + "\n")
|
||||||
|
print(f"\033[91m\033[4m{e}\033[0m")
|
||||||
|
sys.stdout.write('\n---\n') # Add separator before the next function
|
||||||
|
raise e
|
||||||
|
|
||||||
|
return wrapper
|
1
python_task_formatter/TaskFormatter/__init__.py
Normal file
1
python_task_formatter/TaskFormatter/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
from .TaskFormatter import format_output
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,91 @@
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import multiprocessing
|
||||||
|
from functools import wraps
|
||||||
|
import signal
|
||||||
|
import io
|
||||||
|
|
||||||
|
# Global counter for function numbering
|
||||||
|
function_counter = multiprocessing.Value('i', 0)
|
||||||
|
|
||||||
|
def spinner(function_number, func_name, spinner_done, print_lock):
|
||||||
|
spinner_gen = spinner_gen_func()
|
||||||
|
while not spinner_done.is_set():
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[94m{function_number}. {func_name} Running [{next(spinner_gen)}] \033[0m")
|
||||||
|
sys.stdout.flush()
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
def spinner_gen_func():
|
||||||
|
while True:
|
||||||
|
for cursor in "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏":
|
||||||
|
yield cursor
|
||||||
|
|
||||||
|
def format_output(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
with function_counter.get_lock():
|
||||||
|
function_counter.value += 1
|
||||||
|
function_number = function_counter.value
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
func_name = func.__name__
|
||||||
|
spinner_done = multiprocessing.Event()
|
||||||
|
print_lock = multiprocessing.Lock()
|
||||||
|
|
||||||
|
spin_process = multiprocessing.Process(target=spinner, args=(function_number, func_name, spinner_done, print_lock))
|
||||||
|
spin_process.start()
|
||||||
|
|
||||||
|
def handle_exit(signum, frame):
|
||||||
|
raise SystemExit("Process exited")
|
||||||
|
|
||||||
|
signal.signal(signal.SIGTERM, handle_exit)
|
||||||
|
signal.signal(signal.SIGINT, handle_exit)
|
||||||
|
|
||||||
|
buffer = io.StringIO()
|
||||||
|
original_stdout = sys.stdout
|
||||||
|
sys.stdout = buffer
|
||||||
|
|
||||||
|
try:
|
||||||
|
func(*args, **kwargs)
|
||||||
|
duration = time.time() - start_time
|
||||||
|
spinner_done.set()
|
||||||
|
spin_process.join()
|
||||||
|
sys.stdout = original_stdout
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[92m{function_number}. {func_name} Completed [✓] in {duration:.2f}s\033[0m\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
output = buffer.getvalue().strip()
|
||||||
|
if output:
|
||||||
|
sys.stdout.write(output + "\n")
|
||||||
|
sys.stdout.write('\n---\n') # Add separator before the next function
|
||||||
|
except SystemExit as e:
|
||||||
|
duration = time.time() - start_time
|
||||||
|
spinner_done.set()
|
||||||
|
spin_process.join()
|
||||||
|
sys.stdout = original_stdout
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
output = buffer.getvalue().strip()
|
||||||
|
if output:
|
||||||
|
sys.stdout.write(output + "\n")
|
||||||
|
print(f"\033[91m\033[4m{e}\033[0m")
|
||||||
|
sys.stdout.write('\n---\n') # Add separator before the next function
|
||||||
|
raise e
|
||||||
|
except Exception as e:
|
||||||
|
duration = time.time() - start_time
|
||||||
|
spinner_done.set()
|
||||||
|
spin_process.join()
|
||||||
|
sys.stdout = original_stdout
|
||||||
|
with print_lock:
|
||||||
|
sys.stdout.write(f"\r\033[1m\033[4m\033[91m{function_number}. {func_name} Failed [✗] in {duration:.2f}s\033[0m\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
output = buffer.getvalue().strip()
|
||||||
|
if output:
|
||||||
|
sys.stdout.write(output + "\n")
|
||||||
|
print(f"\033[91m\033[4m{e}\033[0m")
|
||||||
|
sys.stdout.write('\n---\n') # Add separator before the next function
|
||||||
|
raise e
|
||||||
|
|
||||||
|
return wrapper
|
|
@ -0,0 +1 @@
|
||||||
|
from .TaskFormatter import format_output
|
BIN
python_task_formatter/dist/TaskFormatter-1.0.2-py3-none-any.whl
vendored
Normal file
BIN
python_task_formatter/dist/TaskFormatter-1.0.2-py3-none-any.whl
vendored
Normal file
Binary file not shown.
BIN
python_task_formatter/dist/TaskFormatter-1.0.2.tar.gz
vendored
Normal file
BIN
python_task_formatter/dist/TaskFormatter-1.0.2.tar.gz
vendored
Normal file
Binary file not shown.
24
python_task_formatter/example.py
Normal file
24
python_task_formatter/example.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from TaskFormatter import format_output
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
@format_output
|
||||||
|
def successful_function():
|
||||||
|
print("Starting")
|
||||||
|
sleep(2)
|
||||||
|
print("Function logic output")
|
||||||
|
|
||||||
|
@format_output
|
||||||
|
def failing_function():
|
||||||
|
print("Just Started")
|
||||||
|
sleep(2)
|
||||||
|
print("Running")
|
||||||
|
sleep(2)
|
||||||
|
print("Done")
|
||||||
|
raise ValueError("Custom Error")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
successful_function()
|
||||||
|
try:
|
||||||
|
failing_function()
|
||||||
|
except Exception as e:
|
||||||
|
print("Caught an exception: ", e)
|
BIN
python_task_formatter/pythonformatterexample.gif
Normal file
BIN
python_task_formatter/pythonformatterexample.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 443 KiB |
3
python_task_formatter/setup.cfg
Normal file
3
python_task_formatter/setup.cfg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# setup.cfg
|
||||||
|
[metadata]
|
||||||
|
description-file = README.md
|
20
python_task_formatter/setup.py
Normal file
20
python_task_formatter/setup.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# setup.py
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="TaskFormatter",
|
||||||
|
version="1.0.2",
|
||||||
|
description="A Python package for function execution status and spinner output",
|
||||||
|
long_description=open('README.md').read(),
|
||||||
|
long_description_content_type='text/markdown',
|
||||||
|
author="Sean Smith",
|
||||||
|
author_email="sean@ssmith.app",
|
||||||
|
url="https://github.com/pitterpatter22/TaskFormatter",
|
||||||
|
packages=find_packages(),
|
||||||
|
classifiers=[
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
],
|
||||||
|
python_requires='>=3.6',
|
||||||
|
)
|
Loading…
Reference in a new issue