Skip to content

Commit d4cc9c2

Browse files
FEAT: Adding the 'Main Template with Telegram' Python Project
1 parent e953a8f commit d4cc9c2

8 files changed

Lines changed: 1047 additions & 0 deletions

File tree

Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
TELEGRAM_API_KEY="your_telegram_api_key_here"
2+
CHAT_ID="your_chat_id_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: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
r"""
2+
================================================================================
3+
Logger Utility Module
4+
================================================================================
5+
Author : Breno Farias da Silva
6+
Created : 2025-12-11
7+
Description :
8+
Dual-channel logger that mirrors console output to both the terminal
9+
(preserving ANSI color sequences when the terminal is a TTY) and a
10+
sanitized log file (ANSI sequences removed). Designed for use in
11+
interactive sessions, background jobs, CI pipelines and Makefile runs.
12+
13+
Behavior:
14+
- When attached to `sys.stdout`/`sys.stderr` the logger writes colored
15+
output to the controlling terminal (when available) and a color-free
16+
record to the specified log file.
17+
- ANSI escape sequences are removed from the file output using a
18+
conservative regex; lines are flushed immediately to keep logs live.
19+
- Provides minimal API: `write()`, `flush()` and `close()` so it can be
20+
used as a drop-in replacement for `sys.stdout`.
21+
22+
Usage:
23+
from Logger import Logger
24+
logger = Logger("./Logs/myrun.log", clean=True)
25+
sys.stdout = logger # optional: redirect all prints to logger
26+
27+
Notes & TODOs:
28+
- Consider adding timestamps, log rotation, and JSON output format.
29+
- The ANSI regex is intentionally simple; adjust if you need broader support.
30+
31+
Dependencies:
32+
- Python >= 3.8 (no external runtime dependencies required)
33+
34+
Assumptions:
35+
- The log file will contain cleaned, human-readable text (no ANSI codes).
36+
- The logger is safe for short-lived scripts and long-running processes.
37+
"""
38+
39+
import os # For interacting with the filesystem
40+
import re # For stripping ANSI escape sequences
41+
import sys # For replacing stdout/stderr
42+
43+
# Regex Constants:
44+
ANSI_ESCAPE_REGEX = re.compile(r"\x1B\[[0-9;]*[a-zA-Z]") # Pattern to remove ANSI colors
45+
46+
# Classes Definitions:
47+
48+
49+
class Logger:
50+
"""
51+
Simple logger class that prints colored messages to the terminal and
52+
writes a cleaned (ANSI-stripped) version to a log file.
53+
54+
Usage:
55+
logger = Logger("./Logs/output.log", clean=True)
56+
logger.info("\x1b[92mHello world\x1b[0m")
57+
58+
:param logfile_path: Path to the log file.
59+
:param clean: If True, truncate the log file on init; otherwise append.
60+
"""
61+
62+
def __init__(self, logfile_path, clean=False):
63+
"""
64+
Initialize the Logger.
65+
66+
:param self: Instance of the Logger class.
67+
:param logfile_path: Path to the log file.
68+
:param clean: If True, truncate the log file on init; otherwise append.
69+
"""
70+
71+
self.logfile_path = logfile_path # Store log file path
72+
73+
parent = os.path.dirname(logfile_path) # Ensure log directory exists
74+
if parent and not os.path.exists(parent): # Create parent directories if needed
75+
os.makedirs(parent, exist_ok=True) # Safe creation
76+
77+
mode = "w" if clean else "a" # Choose file mode based on 'clean' flag
78+
self.logfile = open(logfile_path, mode, encoding="utf-8") # Open log file
79+
self.is_tty = sys.stdout.isatty() # Verify if stdout is a TTY
80+
81+
def write(self, message):
82+
"""
83+
Internal method to write messages to both terminal and log file.
84+
85+
:param self: Instance of the Logger class.
86+
:param message: The message to log.
87+
"""
88+
89+
if message is None: # Ignore None messages
90+
return # Early exit
91+
92+
out = str(message) # Convert message to string
93+
if not out.endswith("\n"): # Ensure newline termination
94+
out += "\n" # Append newline if missing
95+
96+
clean_out = ANSI_ESCAPE_REGEX.sub("", out) # Strip ANSI sequences for log file
97+
98+
try: # Write to log file
99+
self.logfile.write(clean_out) # Write cleaned message
100+
self.logfile.flush() # Ensure immediate write
101+
except Exception: # Fail silently to avoid breaking user code
102+
pass # Silent fail
103+
104+
try: # Write to terminal: colored when TTY, cleaned otherwise
105+
if sys.__stdout__ is not None:
106+
if self.is_tty: # Terminal supports colors
107+
sys.__stdout__.write(out) # Write colored message
108+
sys.__stdout__.flush() # Flush immediately
109+
else: # Terminal does not support colors
110+
sys.__stdout__.write(clean_out) # Write cleaned message
111+
sys.__stdout__.flush() # Flush immediately
112+
except Exception: # Fail silently to avoid breaking user code
113+
pass # Silent fail
114+
115+
def flush(self):
116+
"""
117+
Flush the log file.
118+
119+
:param self: Instance of the Logger class.
120+
"""
121+
122+
try: # Flush log file buffer
123+
self.logfile.flush() # Flush log file
124+
except Exception: # Fail silently
125+
pass # Silent fail
126+
127+
def close(self):
128+
"""
129+
Close the log file.
130+
131+
:param self: Instance of the Logger class.
132+
"""
133+
134+
try: # Close log file
135+
self.logfile.close() # Close log file
136+
except Exception: # Fail silently
137+
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
27+
# On Windows: simply runs the Python script normally
28+
# On Unix-like systems: supports DETACH variable
29+
# - If DETACH is set, runs the script in detached mode and tails the log file
30+
# - Else, runs the script normally
31+
ifeq ($(OS), Windows) # Windows
32+
RUN_AND_LOG = $(PYTHON) $(1)
33+
else
34+
RUN_AND_LOG = \ # Unix-like
35+
if [ -z "$(DETACH)" ]; then \
36+
$(PYTHON) $(1); \
37+
else \
38+
LOG_FILE=$(LOG_DIR)/$$(basename $(1) .py).log; \
39+
nohup $(PYTHON) $(1) > $$LOG_FILE 2>&1 & \
40+
tail -f $$LOG_FILE; \
41+
fi
42+
endif
43+
44+
# Default target
45+
all: run
46+
47+
# Make Rules
48+
run: dependencies
49+
$(ENSURE_LOG_DIR)
50+
$(CLEAR_CMD)
51+
$(call RUN_AND_LOG, ./main.py)
52+
53+
# Create virtual environment if missing
54+
$(VENV):
55+
@echo "Creating virtual environment..."
56+
$(PYTHON_CMD) -m venv $(VENV)
57+
$(PIP) install --upgrade pip
58+
59+
dependencies: $(VENV)
60+
@echo "Installing/Updating Python dependencies..."
61+
$(PIP) install -r requirements.txt
62+
63+
# Generate requirements.txt from current venv
64+
generate_requirements: $(VENV)
65+
$(PIP) freeze > requirements.txt
66+
67+
# Run Telegram Bot
68+
telegram_bot: dependencies
69+
$(ENSURE_LOG_DIR)
70+
$(CLEAR_CMD)
71+
$(call RUN_AND_LOG, ./telegram_bot.py $(ARGS))
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 telegram_bot

0 commit comments

Comments
 (0)