Skip to content

Commit 7cde38f

Browse files
FEAT: Adding the Subtitles Translations with DeepL Python Project
1 parent 5d42335 commit 7cde38f

File tree

7 files changed

+678
-0
lines changed

7 files changed

+678
-0
lines changed
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DEEPL_API_KEY=your_api_key_here
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# System Files
7+
**/.DS_Store
8+
**/Thumbs.db
9+
Icon? # match Icon<CR>
10+
**/Icon? # explicit: match at any nested level
11+
12+
# Ignore the Windows .Desktop Files
13+
**/desktop.ini
14+
15+
# Ignore the Compressed Files
16+
**/.zip
17+
**/.rar
18+
**/*.gz
19+
**/*.7z
20+
**/*.tar.gz
21+
22+
# Ignore the Data Directories
23+
# Input folders
24+
**/Input/*
25+
**/Inputs/*
26+
**/input/*
27+
**/inputs/*
28+
29+
# Output folders
30+
**/Output/*
31+
**/Outputs/*
32+
**/output/*
33+
**/outputs/*
34+
35+
# Data folders
36+
**/Dados/*
37+
**/Data/*
38+
**/dados/*
39+
**/data/*
40+
41+
# Dataset folders
42+
**/Dataset/*
43+
**/Datasets/*
44+
**/dataset/*
45+
**/datasets/*
46+
47+
# Results folders
48+
**/Result/*
49+
**/Results/*
50+
**/result/*
51+
**/results/*
52+
53+
!.assets/*
54+
55+
# Ignore the Data Files
56+
**/*.csv
57+
**/*.json
58+
**/*.xml
59+
**/*.xls
60+
**/*.xlsx
61+
**/*.txt
62+
**/*.parquet
63+
**/*.arff
64+
**/*.png
65+
**/*.jpg
66+
**/*.jpeg
67+
**/*.gif
68+
**/*.bmp
69+
**/*.tiff
70+
**/*.svg
71+
**/*.~lock*
72+
!**/requirements.txt
73+
!**/README.md
74+
75+
# Environments
76+
**/.env
77+
**/.venv
78+
**/env/
79+
**/venv/
80+
**/ENV/
81+
**/env.bak/
82+
**/venv.bak/
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
r"""
2+
================================================================================
3+
Logger Utility Module
4+
================================================================================
5+
Author : Breno Farias da Silva
6+
Created : 2025-12-11
7+
Description :
8+
This module implements a dual-channel logging system designed to capture
9+
all console output produced by Python scripts while preserving ANSI colors
10+
in the terminal and removing them from the log file.
11+
12+
It provides consistent, color-safe logging across interactive terminals,
13+
background executions, CI pipelines, Makefile pipelines, and nohup/systemd
14+
environments.
15+
16+
Key features include:
17+
- Automatic ANSI color stripping for log files
18+
- Full compatibility with interactive and non-interactive terminals
19+
- Mirrored output: terminal (colored) + log file (clean)
20+
- Optional integration by assigning it to sys.stdout/sys.stderr
21+
22+
Usage:
23+
1. Create a Logger instance:
24+
25+
from logger import Logger
26+
logger = Logger("./Logs/output.log", clean=True)
27+
28+
2. (Optional) Redirect all stdout/stderr to the logger:
29+
30+
sys.stdout = logger
31+
sys.stderr = logger
32+
33+
3. Print normally:
34+
35+
print("\x1b[92mHello World\x1b[0m")
36+
37+
Terminal shows colored output.
38+
Log file receives the same text without ANSI escape sequences.
39+
40+
Outputs:
41+
- <path>.log file with fully sanitized (color-free) log output
42+
- Real-time terminal output with correct ANSI handling
43+
44+
TODOs:
45+
- Timestamp prefixing for each log line
46+
- File rotation or size-based log splitting
47+
- CLI flag to force color on/off
48+
- Optional JSON-structured logs
49+
50+
Dependencies:
51+
- Python >= 3.8
52+
- colorama (optional but recommended for Windows)
53+
54+
Assumptions & Notes:
55+
- ANSI escape sequences follow the regex: \x1B\[[0-9;]*[a-zA-Z]
56+
- Log file always stores clean output
57+
- When stdout is not a TTY, color output is automatically disabled
58+
"""
59+
60+
import os # For interacting with the filesystem
61+
import re # For stripping ANSI escape sequences
62+
import sys # For replacing stdout/stderr
63+
64+
# Regex Constants:
65+
ANSI_ESCAPE_REGEX = re.compile(r"\x1B\[[0-9;]*[a-zA-Z]") # Pattern to remove ANSI colors
66+
67+
# Classes Definitions:
68+
69+
class Logger:
70+
"""
71+
Simple logger class that prints colored messages to the terminal and
72+
writes a cleaned (ANSI-stripped) version to a log file.
73+
74+
Usage:
75+
logger = Logger("./Logs/output.log", clean=True)
76+
logger.info("\x1b[92mHello world\x1b[0m")
77+
78+
:param logfile_path: Path to the log file.
79+
:param clean: If True, truncate the log file on init; otherwise append.
80+
"""
81+
82+
def __init__(self, logfile_path, clean=False):
83+
"""
84+
Initialize the Logger.
85+
86+
:param self: Instance of the Logger class.
87+
:param logfile_path: Path to the log file.
88+
:param clean: If True, truncate the log file on init; otherwise append.
89+
"""
90+
91+
self.logfile_path = logfile_path # Store log file path
92+
93+
parent = os.path.dirname(logfile_path) # Ensure log directory exists
94+
if parent and not os.path.exists(parent): # Create parent directories if needed
95+
os.makedirs(parent, exist_ok=True) # Safe creation
96+
97+
mode = "w" if clean else "a" # Choose file mode based on 'clean' flag
98+
self.logfile = open(logfile_path, mode, encoding="utf-8") # Open log file
99+
self.is_tty = sys.stdout.isatty() # Verify if stdout is a TTY
100+
101+
def write(self, message):
102+
"""
103+
Internal method to write messages to both terminal and log file.
104+
105+
:param self: Instance of the Logger class.
106+
:param message: The message to log.
107+
"""
108+
109+
if message is None: # Ignore None messages
110+
return # Early exit
111+
112+
out = str(message) # Convert message to string
113+
if not out.endswith("\n"): # Ensure newline termination
114+
out += "\n" # Append newline if missing
115+
116+
clean_out = ANSI_ESCAPE_REGEX.sub("", out) # Strip ANSI sequences for log file
117+
118+
try: # Write to log file
119+
self.logfile.write(clean_out) # Write cleaned message
120+
self.logfile.flush() # Ensure immediate write
121+
except Exception: # Fail silently to avoid breaking user code
122+
pass # Silent fail
123+
124+
try: # Write to terminal: colored when TTY, cleaned otherwise
125+
if self.is_tty: # Terminal supports colors
126+
sys.__stdout__.write(out) # Write colored message
127+
sys.__stdout__.flush() # Flush immediately
128+
else: # Terminal does not support colors
129+
sys.__stdout__.write(clean_out) # Write cleaned message
130+
sys.__stdout__.flush() # Flush immediately
131+
except Exception: # Fail silently to avoid breaking user code
132+
pass # Silent fail
133+
134+
def flush(self):
135+
"""
136+
Flush the log file.
137+
138+
:param self: Instance of the Logger class.
139+
"""
140+
141+
try: # Flush log file buffer
142+
self.logfile.flush() # Flush log file
143+
except Exception: # Fail silently
144+
pass # Silent fail
145+
146+
def close(self):
147+
"""
148+
Close the log file.
149+
150+
:param self: Instance of the Logger class.
151+
"""
152+
153+
try: # Close log file
154+
self.logfile.close() # Close log file
155+
except Exception: # Fail silently
156+
pass # Silent fail
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Variables
2+
VENV := venv
3+
OS := $(shell uname 2>/dev/null || echo Windows)
4+
5+
# Detect correct Python and Pip commands based on OS
6+
ifeq ($(OS), Windows) # Windows
7+
PYTHON := $(VENV)/Scripts/python.exe
8+
PIP := $(VENV)/Scripts/pip.exe
9+
PYTHON_CMD := python
10+
CLEAR_CMD := cls
11+
TIME_CMD :=
12+
else # Unix-like
13+
PYTHON := $(VENV)/bin/python3
14+
PIP := $(VENV)/bin/pip
15+
PYTHON_CMD := python3
16+
CLEAR_CMD := clear
17+
TIME_CMD := time
18+
endif
19+
20+
# Logs directory
21+
LOG_DIR := ./Logs
22+
23+
# Ensure logs directory exists (cross-platform)
24+
ENSURE_LOG_DIR := @mkdir -p $(LOG_DIR) 2>/dev/null || $(PYTHON_CMD) -c "import os; os.makedirs('$(LOG_DIR)', exist_ok=True)"
25+
26+
# Run-and-log function, supports DETACH variable
27+
# If DETACH is set, runs the script in detached mode and tails the log file
28+
# Else, runs the script normally
29+
# Run-and-log function, DETACH controls detached execution
30+
ifeq ($(OS), Windows) # Windows
31+
RUN_AND_LOG = \
32+
if [ -z "$(DETACH)" ]; then \
33+
$(PYTHON) $(1); \
34+
else \
35+
LOG_FILE=$(LOG_DIR)/$$(basename $(basename $(1))).log; \
36+
start /B cmd /c "$(PYTHON) $(1)"; \
37+
powershell -Command "Get-Content -Path '$$LOG_FILE' -Wait"; \
38+
fi
39+
else # Unix-like
40+
RUN_AND_LOG = \
41+
if [ -z "$(DETACH)" ]; then \
42+
$(PYTHON) $(1); \
43+
else \
44+
LOG_FILE=$(LOG_DIR)/$$(basename $(basename $(1))).log; \
45+
nohup $(PYTHON) $(1) > $$LOG_FILE 2>&1 & \
46+
tail -f $$LOG_FILE; \
47+
fi
48+
endif
49+
50+
# Default target
51+
all: run
52+
53+
# Make Rules
54+
run: dependencies
55+
$(ENSURE_LOG_DIR)
56+
$(CLEAR_CMD)
57+
$(call RUN_AND_LOG, ./main.py)
58+
59+
# Create virtual environment if missing
60+
$(VENV):
61+
@echo "Creating virtual environment..."
62+
$(PYTHON_CMD) -m venv $(VENV)
63+
$(PIP) install --upgrade pip
64+
65+
dependencies: $(VENV)
66+
@echo "Installing/Updating Python dependencies..."
67+
$(PIP) install -r requirements.txt
68+
69+
# Generate requirements.txt from current venv
70+
generate_requirements: $(VENV)
71+
$(PIP) freeze > requirements.txt
72+
73+
# Clean artifacts
74+
clean:
75+
rm -rf $(VENV) || rmdir /S /Q $(VENV) 2>nul
76+
find . -type f -name '*.pyc' -delete || del /S /Q *.pyc 2>nul
77+
find . -type d -name '__pycache__' -delete || rmdir /S /Q __pycache__ 2>nul
78+
79+
.PHONY: all run clean dependencies generate_requirements

0 commit comments

Comments
 (0)