Initial commit.
This commit is contained in:
commit
a61536cb7d
6 changed files with 227 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Python
|
||||||
|
**/__pycache__
|
||||||
|
|
||||||
|
# Temporary
|
||||||
|
**/temp
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Python Loading Bar
|
||||||
|
|
||||||
|
Just a simple loading bar to use in any of your projects. A fully working example can be found in main.py.
|
15
dummy.sh
Executable file
15
dummy.sh
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Simulate a "download" process with fake delays
|
||||||
|
|
||||||
|
echo "Starting download (3 files)..."
|
||||||
|
sleep 2
|
||||||
|
echo "Downloading file 1 of 3..."
|
||||||
|
sleep 2
|
||||||
|
echo "Downloading file 2 of 3..."
|
||||||
|
sleep 2
|
||||||
|
echo "Downloading file 3 of 3..."
|
||||||
|
sleep 2
|
||||||
|
echo "Extracting files..."
|
||||||
|
sleep 1
|
||||||
|
echo "Download complete!"
|
64
main.py
Executable file
64
main.py
Executable file
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import tui
|
||||||
|
from tuicolors import *
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
ROOT_FOLDER = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
def updateprogress(text: str, lb: tui.LoadingBar) -> int:
|
||||||
|
if text == None:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
if lb.getMaximum() == -1 and text.startswith("Starting download"):
|
||||||
|
filetotal=int(text[19])
|
||||||
|
lb.updateLine(1,f"Downloading files ({filetotal})...")
|
||||||
|
lb.setMaximum(filetotal+2)
|
||||||
|
elif lb.getMaximum() > 0:
|
||||||
|
if text.startswith("Downloading file"):
|
||||||
|
filenum = int(text[17])
|
||||||
|
lb.setValue(filenum)
|
||||||
|
if text.startswith("Extracting files..."):
|
||||||
|
lb.updateLine(1,"Extracting files...")
|
||||||
|
lb.incrementValue()
|
||||||
|
if text.startswith("Download complete!"):
|
||||||
|
lb.finish()
|
||||||
|
|
||||||
|
def showprogress():
|
||||||
|
# File info
|
||||||
|
lastentry = ""
|
||||||
|
# Loading bar
|
||||||
|
lb = tui.LoadingBar()
|
||||||
|
lb.addLine(3)
|
||||||
|
lb.updateLine(1,"Preparing download...")
|
||||||
|
|
||||||
|
while not(lb.hasFinished()):
|
||||||
|
newentry = tui.getLastEntry(f"{ROOT_FOLDER}/temp/log.txt")
|
||||||
|
|
||||||
|
# If we get a new string -> update percentage depending on the entry
|
||||||
|
if newentry != lastentry:
|
||||||
|
lastentry = newentry
|
||||||
|
updateprogress(lastentry,lb)
|
||||||
|
|
||||||
|
# Printing and waiting
|
||||||
|
print(f"\r{lb}", end='', flush=True)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# Testing printing capabilities
|
||||||
|
colouredText = tui.colourText("Hello", colour=BRIGHT_RED, backgroundcolour=BLUE)
|
||||||
|
print(colouredText)
|
||||||
|
wow = tui.limitText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec dapibus, tellus a consectetur elementum, ex ex laoreet ligula, sit amet dignissim metus eros vel ligula. Nulla malesuada risus nec libero gravida mattis. Fusce sit amet pharetra felis, congue cursus tellus. Morbi faucibus nisi at gravida viverra. Praesent a posuere ex. In hac habitasse platea dictumst. Sed sed feugiat leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec tincidunt porttitor arcu vel cursus. Vestibulum luctus quam vitae gravida viverra. ")
|
||||||
|
print(wow)
|
||||||
|
wow = tui.limitText("Tu ne parleras pas", 5)
|
||||||
|
print(wow)
|
||||||
|
|
||||||
|
os.makedirs(ROOT_FOLDER + "/temp", exist_ok=True)
|
||||||
|
with open(ROOT_FOLDER + "/temp/log.txt", "a") as log_file:
|
||||||
|
thread = threading.Thread(target=showprogress)
|
||||||
|
thread.start()
|
||||||
|
subprocess.run(["bash", "dummy.sh"], stdout=log_file, stderr=log_file)
|
||||||
|
thread.join()
|
||||||
|
print(tui.colourText("\nSuccessfully downloaded project!", GREEN))
|
123
tui.py
Normal file
123
tui.py
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
from tuicolors import WHITE, BRIGHT_BLACK, GREEN, RED
|
||||||
|
import os
|
||||||
|
import math
|
||||||
|
|
||||||
|
SPIN_STATUS = ['|','/','-','\\']
|
||||||
|
CORRECT = "\033[92mv\033[00m"
|
||||||
|
INCORRECT = "\033[91mX\033[00m"
|
||||||
|
UP_LINE = "\033[A"
|
||||||
|
|
||||||
|
def colourText(string: str, colour: int = WHITE, backgroundcolour: int = None) -> str:
|
||||||
|
if backgroundcolour is not None:
|
||||||
|
bg_code = backgroundcolour + 10
|
||||||
|
return f"\033[{colour};{bg_code}m{string}\033[0m"
|
||||||
|
else:
|
||||||
|
return f"\033[{colour}m{string}\033[0m"
|
||||||
|
|
||||||
|
def limitText(string: str, limit: int=-1) -> str:
|
||||||
|
if limit == -1:
|
||||||
|
limit = os.get_terminal_size().columns-3
|
||||||
|
if len(string) > limit:
|
||||||
|
return string[:limit]+"..."
|
||||||
|
else:
|
||||||
|
return string
|
||||||
|
|
||||||
|
class LoadingBar:
|
||||||
|
def __init__(self):
|
||||||
|
if os.get_terminal_size().columns < 57:
|
||||||
|
self.size = os.get_terminal_size().columns - 5
|
||||||
|
else:
|
||||||
|
self.size = 55
|
||||||
|
self.percentage = 0.0
|
||||||
|
self.spin = 0
|
||||||
|
self.line = []
|
||||||
|
self.first = True
|
||||||
|
self.max = -1
|
||||||
|
|
||||||
|
def addLine(self, line: int):
|
||||||
|
self.line = [""] * line
|
||||||
|
|
||||||
|
def updateLine(self, index: int, text: str):
|
||||||
|
self.line[index] = f"{text}{' '*(os.get_terminal_size().columns-len(text))}"
|
||||||
|
|
||||||
|
def setPercentage(self, percentage: float):
|
||||||
|
if percentage >= 0.0 and percentage <= 100.0:
|
||||||
|
self.percentage = percentage
|
||||||
|
|
||||||
|
def getPercentage(self) -> float:
|
||||||
|
return self.percentage
|
||||||
|
|
||||||
|
def setMaximum(self, max: int):
|
||||||
|
self.max = max
|
||||||
|
|
||||||
|
def getMaximum(self) -> int:
|
||||||
|
return self.max
|
||||||
|
|
||||||
|
def setValue(self, value: int):
|
||||||
|
if self.max == -1:
|
||||||
|
raise ValueError("Please set the maximum before setValue by calling LoadingBar.setMaximum()")
|
||||||
|
elif value > self.max:
|
||||||
|
raise ValueError(f"Cannot set a value superior to LoadingBar maximum: {self.max}")
|
||||||
|
else:
|
||||||
|
self.percentage = (value/self.max)*100.0
|
||||||
|
|
||||||
|
def incrementValue(self):
|
||||||
|
if self.max == -1:
|
||||||
|
raise ValueError("Please set the maximum before incrementValue by calling LoadingBar.setMaximum()")
|
||||||
|
value = math.floor((self.percentage/100.0)*self.max)+1
|
||||||
|
self.setValue(value)
|
||||||
|
|
||||||
|
def finish(self):
|
||||||
|
self.percentage = 100.0
|
||||||
|
|
||||||
|
def hasFinished(self) -> bool:
|
||||||
|
return self.percentage == 100.0
|
||||||
|
|
||||||
|
def updateSpin(self):
|
||||||
|
self.spin += 1
|
||||||
|
if self.spin >= len(SPIN_STATUS):
|
||||||
|
self.spin = 0
|
||||||
|
|
||||||
|
def getSpin(self) -> str:
|
||||||
|
if self.percentage >= 100.0:
|
||||||
|
return CORRECT
|
||||||
|
else:
|
||||||
|
return SPIN_STATUS[self.spin]
|
||||||
|
|
||||||
|
def getBackgroundColour(self) -> str:
|
||||||
|
if self.percentage >= 100.0:
|
||||||
|
return GREEN
|
||||||
|
else:
|
||||||
|
return WHITE
|
||||||
|
|
||||||
|
def getUpLine(self) -> str:
|
||||||
|
if not(self.first):
|
||||||
|
return UP_LINE*len(self.line)
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
print("\n"*(len(self.line)+1), end='', flush=True)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
filled = math.floor((self.percentage/100)*(self.size-5))
|
||||||
|
empty = (self.size-5)-filled
|
||||||
|
filled_str = colourText(" " * filled, backgroundcolour=self.getBackgroundColour())
|
||||||
|
empty_str = colourText(" " * empty, backgroundcolour=BRIGHT_BLACK)
|
||||||
|
formatted_percent = colourText(str(int(self.percentage)), self.getBackgroundColour())
|
||||||
|
|
||||||
|
ret = self.getUpLine()
|
||||||
|
for l in self.line:
|
||||||
|
ret += f"{l}\n"
|
||||||
|
ret += f"{self.getSpin()} {filled_str}{empty_str} {formatted_percent}%"
|
||||||
|
self.updateSpin()
|
||||||
|
self.first = False
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def getLastEntry(filepath: str) -> str:
|
||||||
|
with open(filepath, "r") as log_file:
|
||||||
|
log_file.seek(0)
|
||||||
|
new_data = log_file.readlines()
|
||||||
|
if new_data:
|
||||||
|
last_line = new_data[-1].strip()
|
||||||
|
return last_line
|
17
tuicolors.py
Normal file
17
tuicolors.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
BLACK = 30
|
||||||
|
RED = 31
|
||||||
|
GREEN = 32
|
||||||
|
YELLOW = 33
|
||||||
|
BLUE = 34
|
||||||
|
MAGENTA = 35
|
||||||
|
CYAN = 36
|
||||||
|
WHITE = 37
|
||||||
|
|
||||||
|
BRIGHT_BLACK = 90
|
||||||
|
BRIGHT_RED = 91
|
||||||
|
BRIGHT_GREEN = 92
|
||||||
|
BRIGHT_YELLOW = 93
|
||||||
|
BRIGHT_BLUE = 94
|
||||||
|
BRIGHT_MAGENTA = 95
|
||||||
|
BRIGHT_CYAN = 96
|
||||||
|
BRIGHT_WHITE = 97
|
Loading…
Add table
Reference in a new issue