mirror of
https://github.com/johndoe6345789/tustu.git
synced 2026-04-24 13:45:00 +00:00
feat: Add unified command-line utility for TunerStudio project
- Introduced `tustu_tools.py` to consolidate various scripts into a single command-line tool. - Implemented key generation functionality with multiple algorithms. - Added dummy data generation and email formatting capabilities. - Included structure analysis and constructor fixing for Java files. - Created wrapper script `tustu-tools` for easy access to the utility. - Developed test scripts for dummy data and email generation. - Added a script for reorganizing the app directory structure.
This commit is contained in:
6
scripts/.markdownlint.json
Normal file
6
scripts/.markdownlint.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD013": false,
|
||||
"MD033": false,
|
||||
"MD041": false
|
||||
}
|
||||
68
scripts/INDEX.md
Normal file
68
scripts/INDEX.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Scripts Folder - Quick Index
|
||||
|
||||
Quick navigation guide for the scripts folder.
|
||||
|
||||
## 🎯 What You Need
|
||||
|
||||
| I want to... | Go to... |
|
||||
|--------------|----------|
|
||||
| Generate registration keys, test data, or use tools | `tustu_tools.py` - [Documentation](TUSTU_TOOLS_README.md) |
|
||||
| Understand the folder organization | [README_SCRIPTS.md](README_SCRIPTS.md) |
|
||||
| Access original scripts | [legacy/](legacy/) folder - [Details](legacy/README.md) |
|
||||
| View analysis data | [data/](data/) folder - [Details](data/README.md) |
|
||||
|
||||
## 📖 Documentation Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `README.md` | Quick overview and examples |
|
||||
| `README_SCRIPTS.md` | Detailed migration guide |
|
||||
| `TUSTU_TOOLS_README.md` | Complete tool documentation |
|
||||
| `INDEX.md` | This file (quick navigation) |
|
||||
|
||||
## 🔧 Main Tool
|
||||
|
||||
**File:** `tustu_tools.py`
|
||||
|
||||
**Quick Commands:**
|
||||
```bash
|
||||
python3 tustu_tools.py --help # Show all commands
|
||||
python3 tustu_tools.py gen-key -t # Generate key with test data
|
||||
python3 tustu_tools.py test-data -n 5 # Generate 5 test sets
|
||||
python3 tustu_tools.py gui # Launch GUI
|
||||
```
|
||||
|
||||
**From project root:**
|
||||
```bash
|
||||
./tustu-tools --help
|
||||
./tustu-tools gen-key --test-data
|
||||
```
|
||||
|
||||
## 📂 Folder Contents
|
||||
|
||||
### Main Files (scripts/)
|
||||
- ⭐ `tustu_tools.py` - Unified command-line tool
|
||||
- 📖 `*.md` - Documentation files
|
||||
|
||||
### legacy/
|
||||
- All original individual Python scripts
|
||||
- Preserved for reference
|
||||
- See [legacy/README.md](legacy/README.md)
|
||||
|
||||
### data/
|
||||
- JSON mapping and analysis files
|
||||
- Generated data files
|
||||
- See [data/README.md](data/README.md)
|
||||
|
||||
## 🚦 Getting Started
|
||||
|
||||
1. **First time?** Start with [README.md](README.md)
|
||||
2. **Need examples?** Check [TUSTU_TOOLS_README.md](TUSTU_TOOLS_README.md)
|
||||
3. **Migrating code?** Read [README_SCRIPTS.md](README_SCRIPTS.md)
|
||||
|
||||
## 🔗 Quick Links
|
||||
|
||||
- [Complete Documentation](TUSTU_TOOLS_README.md)
|
||||
- [Legacy Scripts Info](legacy/README.md)
|
||||
- [Data Files Info](data/README.md)
|
||||
- [Project Root](../)
|
||||
129
scripts/MARKDOWN_STYLE.md
Normal file
129
scripts/MARKDOWN_STYLE.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Markdown Style Guide
|
||||
|
||||
This document describes the markdown style used in the scripts folder documentation.
|
||||
|
||||
## Conventions
|
||||
|
||||
### Headers
|
||||
|
||||
- Use ATX-style headers (`#` prefix)
|
||||
- Add blank line before and after headers
|
||||
- Use sentence case for titles
|
||||
|
||||
### Code Blocks
|
||||
|
||||
- Always specify language for syntax highlighting
|
||||
- Use \`\`\`bash for shell commands
|
||||
- Use \`\`\`python for Python code
|
||||
- Use inline \` for command names and file names
|
||||
|
||||
### Lists
|
||||
|
||||
- Use `-` for unordered lists
|
||||
- Add blank line before and after lists
|
||||
- Use consistent indentation (2 spaces)
|
||||
|
||||
### Tables
|
||||
|
||||
- Use pipes (`|`) for table formatting
|
||||
- Add header separator row
|
||||
- Align columns for readability
|
||||
- Keep tables simple (max 3-4 columns)
|
||||
|
||||
### Emphasis
|
||||
|
||||
- Use `**bold**` for important terms
|
||||
- Use `*italic*` for emphasis
|
||||
- Use `code` for technical terms
|
||||
- Use > for blockquotes/callouts
|
||||
|
||||
### Links
|
||||
|
||||
- Use relative links within project
|
||||
- Use descriptive link text
|
||||
- Format: `[text](path/to/file.md)`
|
||||
|
||||
### Emojis
|
||||
|
||||
Used sparingly for visual organization:
|
||||
|
||||
- 🎯 Goals/objectives
|
||||
- ✅ Completed items
|
||||
- ⭐ Important/featured
|
||||
- 📖 Documentation
|
||||
- 💾 Data/storage
|
||||
- 📦 Archives/legacy
|
||||
- 🚀 Quick start
|
||||
- <20><>️ Tools
|
||||
- 📁 File structure
|
||||
|
||||
## File Types
|
||||
|
||||
### INDEX.md
|
||||
- Quick navigation only
|
||||
- Table format for clarity
|
||||
- Links to all major sections
|
||||
|
||||
### README.md
|
||||
- Brief overview
|
||||
- Quick start examples
|
||||
- Links to detailed docs
|
||||
|
||||
### README_SCRIPTS.md
|
||||
- Detailed migration guide
|
||||
- Before/after comparisons
|
||||
- Complete command reference
|
||||
|
||||
### TUSTU_TOOLS_README.md
|
||||
- Complete tool documentation
|
||||
- All commands with examples
|
||||
- Full reference guide
|
||||
|
||||
## Example Patterns
|
||||
|
||||
### Command Reference Table
|
||||
|
||||
\`\`\`markdown
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| \`command\` | What it does |
|
||||
\`\`\`
|
||||
|
||||
### Quick Start Section
|
||||
|
||||
\`\`\`markdown
|
||||
## Quick Start
|
||||
|
||||
\`\`\`bash
|
||||
./command --option
|
||||
\`\`\`
|
||||
\`\`\`
|
||||
|
||||
### File Structure
|
||||
|
||||
\`\`\`markdown
|
||||
folder/
|
||||
├── file1.py # Description
|
||||
├── file2.md # Description
|
||||
└── subfolder/ # Description
|
||||
\`\`\`
|
||||
|
||||
## Validation
|
||||
|
||||
Files follow these principles:
|
||||
|
||||
1. **Clear hierarchy** - Logical header structure
|
||||
2. **Scannable** - Use tables and lists
|
||||
3. **Consistent** - Same patterns throughout
|
||||
4. **Actionable** - Clear examples
|
||||
5. **Linked** - Easy navigation
|
||||
|
||||
## Maintenance
|
||||
|
||||
When adding content:
|
||||
|
||||
- Match existing style
|
||||
- Update table of contents if present
|
||||
- Test all links
|
||||
- Check code examples work
|
||||
- Keep line length reasonable
|
||||
75
scripts/README.md
Normal file
75
scripts/README.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Scripts Folder
|
||||
|
||||
Clean, organized tool collection for the TuStu project.
|
||||
|
||||
> **Quick Start:** `./tustu-tools gen-key --test-data` (from project root)
|
||||
> **Full Docs:** [TUSTU_TOOLS_README.md](TUSTU_TOOLS_README.md)
|
||||
|
||||
## 📁 Structure
|
||||
|
||||
```
|
||||
scripts/
|
||||
├── tustu_tools.py ⭐ Main unified tool
|
||||
├── TUSTU_TOOLS_README.md 📖 Complete documentation
|
||||
├── README_SCRIPTS.md 📋 Overview (detailed)
|
||||
├── data/ 💾 Analysis & mapping data
|
||||
└── legacy/ 📦 Original individual scripts
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
```bash
|
||||
# From project root
|
||||
./tustu-tools gen-key --test-data
|
||||
./tustu-tools test-data -n 5
|
||||
|
||||
# From scripts folder
|
||||
python3 tustu_tools.py gen-key --test-data
|
||||
python3 tustu_tools.py --help
|
||||
```
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- **TUSTU_TOOLS_README.md** - Complete usage guide with examples
|
||||
- **README_SCRIPTS.md** - Detailed overview and migration guide
|
||||
- **legacy/README.md** - Info about original scripts
|
||||
- **data/README.md** - JSON data files documentation
|
||||
|
||||
## 🛠️ Main Tool
|
||||
|
||||
**File:** `tustu_tools.py` (executable)
|
||||
|
||||
Unified command-line interface providing:
|
||||
|
||||
- **Registration key generation** - All algorithms (4/5/7/8 param)
|
||||
- **Test data creation** - Realistic dummy data with valid keys
|
||||
- **Java constructor fixing** - Automated code repairs
|
||||
- **Project structure analysis** - Package and file organization
|
||||
- **GUI launcher** - PyQt6 registration interface
|
||||
|
||||
Run `./tustu-tools --help` for full command list.
|
||||
|
||||
## 📦 Subfolders
|
||||
|
||||
| Folder | Contents | Purpose |
|
||||
|--------|----------|---------|
|
||||
| **legacy/** | 8 original Python scripts | Preserved for reference; use `tustu_tools.py` instead |
|
||||
| **data/** | 4 JSON analysis files | Generated mapping/analysis data (not version controlled) |
|
||||
|
||||
## 💡 Examples
|
||||
|
||||
```bash
|
||||
# Generate 10 test registration keys
|
||||
./tustu-tools test-data -n 10 --email-format > keys.txt
|
||||
|
||||
# Fix Java constructors in app directory
|
||||
./tustu-tools fix-constructors -d ./app
|
||||
|
||||
# Analyze project structure
|
||||
./tustu-tools analyze -o structure.json
|
||||
|
||||
# Launch GUI
|
||||
./tustu-tools gui
|
||||
```
|
||||
|
||||
For more examples, see `TUSTU_TOOLS_README.md`
|
||||
206
scripts/README_SCRIPTS.md
Normal file
206
scripts/README_SCRIPTS.md
Normal file
@@ -0,0 +1,206 @@
|
||||
# Scripts Folder - Consolidated Tool
|
||||
|
||||
All individual scripts have been consolidated into **`tustu_tools.py`** - a unified command-line tool with argparse interface.
|
||||
|
||||
## Organization
|
||||
|
||||
| Component | Description |
|
||||
|-----------|-------------|
|
||||
| **Main tool** | `tustu_tools.py` - Unified CLI with all features |
|
||||
| **Documentation** | Multiple README files with complete usage information |
|
||||
| **legacy/** | Original individual scripts (preserved for reference) |
|
||||
| **data/** | JSON analysis and mapping files |
|
||||
|
||||
## Unified Tool
|
||||
|
||||
**Main Script:** `tustu_tools.py`
|
||||
|
||||
This consolidated tool provides all functionality from the following scripts:
|
||||
|
||||
### Merged Scripts
|
||||
|
||||
| Original Script | Functionality | New Command |
|
||||
|----------------|---------------|-------------|
|
||||
| `registration_gui.py` | PyQt6 GUI for key generation | `tustu_tools.py gui` |
|
||||
| `demo_test_data_ui.py` | Demo of test data loading | Integrated into all commands |
|
||||
| `test_dummy_data.py` | Test data generation | `tustu_tools.py test-data` |
|
||||
| `test_email_generation.py` | Email format generation | `tustu_tools.py gen-key --email-format` |
|
||||
| `fix_constructors.py` | Fix Java constructor names | `tustu_tools.py fix-constructors` |
|
||||
| `fix_constructors_v2.py` | Alternative constructor fixer | Merged into fix-constructors |
|
||||
| `reorganize_structure.py` | Project structure analysis | `tustu_tools.py analyze` |
|
||||
| `rename_obfuscated_files.py` | Rename obfuscated Java files | Core utilities available |
|
||||
|
||||
### Folder Structure
|
||||
|
||||
```
|
||||
scripts/
|
||||
├── tustu_tools.py # Main unified tool
|
||||
├── TUSTU_TOOLS_README.md # Complete documentation
|
||||
├── README_SCRIPTS.md # This file
|
||||
├── data/ # JSON data files
|
||||
│ ├── README.md
|
||||
│ ├── COMPLETE_RENAME_MAPPING.json
|
||||
│ ├── JAVA_ANALYSIS_RESULTS.json
|
||||
│ ├── PACKAGE_MAPPING.json
|
||||
│ └── STRUCTURE_ANALYSIS.json
|
||||
└── legacy/ # Original individual scripts
|
||||
├── README.md
|
||||
├── registration_gui.py
|
||||
├── demo_test_data_ui.py
|
||||
├── test_dummy_data.py
|
||||
├── test_email_generation.py
|
||||
├── fix_constructors.py
|
||||
├── fix_constructors_v2.py
|
||||
├── reorganize_structure.py
|
||||
└── rename_obfuscated_files.py
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
From the project root:
|
||||
```bash
|
||||
# Show all available commands
|
||||
./tustu-tools --help
|
||||
|
||||
# Generate test data
|
||||
./tustu-tools test-data -n 5
|
||||
|
||||
# Generate a registration key
|
||||
./tustu-tools gen-key --test-data
|
||||
|
||||
# Fix Java constructors
|
||||
./tustu-tools fix-constructors -d ./app
|
||||
|
||||
# Analyze project structure
|
||||
./tustu-tools analyze
|
||||
```
|
||||
|
||||
From the scripts folder:
|
||||
```bash
|
||||
# Show all available commands
|
||||
python3 tustu_tools.py --help
|
||||
|
||||
# Generate test data
|
||||
python3 tustu_tools.py test-data -n 5
|
||||
```
|
||||
|
||||
## Folder Structure
|
||||
|
||||
```
|
||||
scripts/
|
||||
├── tustu_tools.py # ⭐ Main unified tool
|
||||
├── TUSTU_TOOLS_README.md # Complete documentation
|
||||
├── README_SCRIPTS.md # This file
|
||||
├── data/ # JSON data files
|
||||
│ ├── README.md
|
||||
│ ├── COMPLETE_RENAME_MAPPING.json
|
||||
│ ├── JAVA_ANALYSIS_RESULTS.json
|
||||
│ ├── PACKAGE_MAPPING.json
|
||||
│ └── STRUCTURE_ANALYSIS.json
|
||||
└── legacy/ # Original individual scripts
|
||||
├── README.md
|
||||
├── registration_gui.py
|
||||
├── demo_test_data_ui.py
|
||||
├── test_dummy_data.py
|
||||
├── test_email_generation.py
|
||||
├── fix_constructors.py
|
||||
├── fix_constructors_v2.py
|
||||
├── reorganize_structure.py
|
||||
└── rename_obfuscated_files.py
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
See **`TUSTU_TOOLS_README.md`** for complete documentation including:
|
||||
- All available commands
|
||||
- Detailed usage examples
|
||||
- Command reference
|
||||
- Migration guide from old scripts
|
||||
|
||||
## Legacy Scripts
|
||||
|
||||
The original individual scripts are preserved in this folder for reference purposes. However, **`tustu_tools.py` is now the recommended way** to access all functionality.
|
||||
|
||||
## Key Benefits
|
||||
|
||||
| Benefit | Impact |
|
||||
|---------|--------|
|
||||
| **Single Entry Point** | One tool instead of 8+ scripts |
|
||||
| **Consistent Interface** | All commands use argparse |
|
||||
| **Better Help** | `--help` for every command |
|
||||
| **Easy Discovery** | Features are obvious |
|
||||
| **Simple Maintenance** | One codebase to update |
|
||||
| **Clean Structure** | Organized folders |
|
||||
|
||||
### Original Scripts Still Work
|
||||
|
||||
If you prefer, you can still run the original scripts directly:
|
||||
```bash
|
||||
python3 registration_gui.py # Launch GUI
|
||||
python3 test_dummy_data.py # Generate test data
|
||||
python3 fix_constructors.py # Fix constructors
|
||||
```
|
||||
|
||||
However, we recommend using `tustu_tools.py` for all new work.
|
||||
|
||||
## Examples
|
||||
|
||||
### Before (Multiple Scripts)
|
||||
|
||||
```bash
|
||||
python3 test_dummy_data.py
|
||||
python3 test_email_generation.py
|
||||
python3 fix_constructors.py
|
||||
python3 reorganize_structure.py
|
||||
```
|
||||
|
||||
### After (Unified Tool)
|
||||
|
||||
```bash
|
||||
./tustu-tools test-data -n 5
|
||||
./tustu-tools gen-key --test-data --email-format
|
||||
./tustu-tools fix-constructors -d ./app
|
||||
./tustu-tools analyze -o report.json
|
||||
```
|
||||
|
||||
## Commands Overview
|
||||
|
||||
Run from project root with `./tustu-tools` or from scripts folder with `python3 tustu_tools.py`:
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `gen-key` | Generate registration keys (4/5/7/8 param algorithms) |
|
||||
| `test-data` | Generate test data sets with valid keys |
|
||||
| `fix-constructors` | Fix misnamed Java constructors |
|
||||
| `analyze` | Analyze project structure and packages |
|
||||
| `gui` | Launch PyQt6 GUI (requires PyQt6) |
|
||||
|
||||
**Detailed help:**
|
||||
|
||||
```bash
|
||||
./tustu-tools <command> --help
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
No installation needed! Just run the script:
|
||||
```bash
|
||||
python3 scripts/tustu_tools.py [command]
|
||||
```
|
||||
|
||||
Or use the wrapper from project root:
|
||||
```bash
|
||||
./tustu-tools [command]
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
Core functionality requires only Python 3 standard library.
|
||||
|
||||
Optional dependencies:
|
||||
- **PyQt6** - Required for GUI: `pip install PyQt6`
|
||||
|
||||
## See Also
|
||||
|
||||
- `TUSTU_TOOLS_README.md` - Complete documentation
|
||||
- `../README.md` - Project root documentation
|
||||
86
scripts/REORGANIZATION_SUMMARY.md
Normal file
86
scripts/REORGANIZATION_SUMMARY.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Scripts Reorganization Summary
|
||||
|
||||
**Date:** January 11, 2026
|
||||
**Status:** ✅ Complete and tested
|
||||
|
||||
The scripts folder has been successfully reorganized for clarity and maintainability.
|
||||
|
||||
### What Was Done
|
||||
|
||||
1. **Created Unified Tool** - `tustu_tools.py`
|
||||
- Merged 8 individual scripts into one
|
||||
- Argparse-based CLI with subcommands
|
||||
- Comprehensive help system
|
||||
|
||||
2. **Organized Folder Structure**
|
||||
```
|
||||
scripts/
|
||||
├── tustu_tools.py ⭐ Main tool
|
||||
├── *.md 📖 Documentation (5 files)
|
||||
├── data/ 💾 JSON data files
|
||||
└── legacy/ 📦 Original scripts
|
||||
```
|
||||
|
||||
3. **Created Documentation**
|
||||
- `README.md` - Quick overview and examples
|
||||
- `INDEX.md` - Quick navigation guide
|
||||
- `README_SCRIPTS.md` - Detailed migration info
|
||||
- `TUSTU_TOOLS_README.md` - Complete tool docs
|
||||
- `legacy/README.md` - Legacy scripts info
|
||||
- `data/README.md` - Data files documentation
|
||||
|
||||
4. **Moved Files**
|
||||
- 8 Python scripts → `legacy/`
|
||||
- 4 JSON files → `data/`
|
||||
- Clean main folder with only essentials
|
||||
|
||||
### Folder Details
|
||||
|
||||
#### Main Scripts Folder
|
||||
- **1 main tool** - `tustu_tools.py` (executable)
|
||||
- **5 documentation files** - Complete guides and references
|
||||
|
||||
#### legacy/ Subfolder
|
||||
- 8 original Python scripts preserved for reference
|
||||
- Still functional if needed individually
|
||||
- README explains how to use them
|
||||
|
||||
#### data/ Subfolder
|
||||
- 4 JSON analysis/mapping files
|
||||
- Generated data from previous runs
|
||||
- README documents each file's purpose
|
||||
|
||||
### Benefits Achieved
|
||||
|
||||
✅ **Clean organization** - Clear separation of active vs legacy code
|
||||
✅ **Easy navigation** - Well-documented with multiple README files
|
||||
✅ **Maintained functionality** - All features still accessible
|
||||
✅ **Better discoverability** - Single tool with `--help` for everything
|
||||
✅ **Preserved history** - Original scripts kept for reference
|
||||
|
||||
### Testing Confirmed
|
||||
|
||||
All commands tested and working:
|
||||
- ✅ `gen-key` - Registration key generation
|
||||
- ✅ `test-data` - Test data creation
|
||||
- ✅ `fix-constructors` - Java constructor fixing
|
||||
- ✅ `analyze` - Project analysis
|
||||
- ✅ `gui` - GUI launcher (imports from legacy/)
|
||||
|
||||
### Usage From Project Root
|
||||
|
||||
```bash
|
||||
./tustu-tools gen-key --test-data
|
||||
./tustu-tools test-data -n 5
|
||||
./tustu-tools --help
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
The scripts folder is now clean, organized, and well-documented. All functionality is preserved and enhanced with a unified CLI interface.
|
||||
|
||||
### Next Steps
|
||||
|
||||
- Use `./tustu-tools` from project root for all operations
|
||||
- Refer to `TUSTU_TOOLS_README.md` for complete documentation
|
||||
- Legacy scripts remain available in `legacy/` if needed
|
||||
330
scripts/TUSTU_TOOLS_README.md
Normal file
330
scripts/TUSTU_TOOLS_README.md
Normal file
@@ -0,0 +1,330 @@
|
||||
# TuStu Tools - Unified Command-Line Utility
|
||||
|
||||
A comprehensive command-line tool that consolidates all scripts from the `scripts/` folder into a single, easy-to-use utility with argparse-based interface.
|
||||
|
||||
> **TL;DR:** Run `./tustu-tools --help` from project root for all commands.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Features](#features)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Available Commands](#available-commands)
|
||||
- [Command Reference](#command-reference)
|
||||
- [Examples](#examples)
|
||||
- [Migration Guide](#migration-from-individual-scripts)
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
This tool combines functionality from:
|
||||
|
||||
| Original Script | New Command | Description |
|
||||
|-----------------|-------------|-------------|
|
||||
| `registration_gui.py` | `gui` | PyQt6 GUI for key generation |
|
||||
| `demo_test_data_ui.py` + `test_dummy_data.py` | `test-data` | Generate test data with valid keys |
|
||||
| `test_email_generation.py` | `gen-key --email-format` | Create registration emails |
|
||||
| `fix_constructors.py` + `fix_constructors_v2.py` | `fix-constructors` | Fix Java constructor names |
|
||||
| `reorganize_structure.py` | `analyze` | Analyze project structure |
|
||||
| `rename_obfuscated_files.py` | Core utilities | File renaming functions |
|
||||
|
||||
## Installation
|
||||
|
||||
No installation needed! The tool uses Python 3 standard library.
|
||||
|
||||
**Optional:** For GUI support, install PyQt6:
|
||||
|
||||
```bash
|
||||
pip install PyQt6
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### General Syntax
|
||||
```bash
|
||||
./tustu_tools.py <command> [options]
|
||||
```
|
||||
|
||||
## Available Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `gen-key` | Generate registration keys (4/5/7/8 parameter algorithms) |
|
||||
| `test-data` | Generate test data sets with valid keys |
|
||||
| `fix-constructors` | Fix misnamed Java constructors |
|
||||
| `analyze` | Analyze project structure and packages |
|
||||
| `gui` | Launch PyQt6 registration GUI (requires PyQt6) |
|
||||
|
||||
**Get help for any command:**
|
||||
|
||||
```bash
|
||||
./tustu-tools <command> --help
|
||||
```
|
||||
|
||||
#### 1. Generate Registration Keys
|
||||
|
||||
Generate a registration key with test data:
|
||||
```bash
|
||||
./tustu_tools.py gen-key --test-data --algorithm 5param
|
||||
```
|
||||
|
||||
Generate a key with specific parameters:
|
||||
```bash
|
||||
./tustu_tools.py gen-key \
|
||||
--first-name John \
|
||||
--last-name Doe \
|
||||
--email john@example.com \
|
||||
--product MegaLogViewer \
|
||||
--secret secret123
|
||||
```
|
||||
|
||||
Generate with email format:
|
||||
```bash
|
||||
./tustu_tools.py gen-key --test-data --email-format
|
||||
```
|
||||
|
||||
Algorithms available:
|
||||
- `4param` - Basic obfuscation (4 parameters)
|
||||
- `5param` - Standard (5 parameters) - **default**
|
||||
- `7param` - Enhanced (7 parameters)
|
||||
- `8param` - Full (8 parameters)
|
||||
|
||||
#### 2. Generate Test Data
|
||||
|
||||
Generate 5 test data sets with valid keys:
|
||||
```bash
|
||||
./tustu_tools.py test-data -n 5
|
||||
```
|
||||
|
||||
Generate with email format:
|
||||
```bash
|
||||
./tustu_tools.py test-data -n 3 --email-format
|
||||
```
|
||||
|
||||
#### 3. Fix Java Constructors
|
||||
|
||||
Fix misnamed constructors in the app directory:
|
||||
```bash
|
||||
./tustu_tools.py fix-constructors -d ./app
|
||||
```
|
||||
|
||||
Scan a specific directory:
|
||||
```bash
|
||||
./tustu_tools.py fix-constructors -d /path/to/java/files
|
||||
```
|
||||
|
||||
#### 4. Analyze Project Structure
|
||||
|
||||
Analyze the current project structure:
|
||||
```bash
|
||||
./tustu_tools.py analyze
|
||||
```
|
||||
|
||||
Save analysis to a JSON file:
|
||||
```bash
|
||||
./tustu_tools.py analyze -o structure_report.json
|
||||
```
|
||||
|
||||
Analyze a different project:
|
||||
```bash
|
||||
./tustu_tools.py analyze -b /path/to/project -o report.json
|
||||
```
|
||||
|
||||
#### 5. Launch GUI
|
||||
|
||||
Launch the PyQt6 registration GUI (requires PyQt6):
|
||||
```bash
|
||||
./tustu_tools.py gui
|
||||
```
|
||||
|
||||
## Command Reference
|
||||
|
||||
### `gen-key` - Generate Registration Key
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-f, --first-name` | First name |
|
||||
| `-l, --last-name` | Last name |
|
||||
| `-e, --email` | Email address |
|
||||
| `-p, --product` | Product name |
|
||||
| `-s, --secret` | Secret key |
|
||||
| `--serial` | Serial number |
|
||||
| `-a, --algorithm` | Algorithm: 4param, 5param, 7param, 8param (default: 5param) |
|
||||
| `--field1` | Additional field 1 (for 7/8 param algorithms) |
|
||||
| `--field2` | Additional field 2 (for 7/8 param algorithms) |
|
||||
| `-t, --test-data` | Generate random test data |
|
||||
| `--email-format` | Output in email format |
|
||||
|
||||
### `test-data` - Generate Test Data
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-n, --count` | Number of test data sets (default: 5) |
|
||||
| `--email-format` | Output in email format |
|
||||
|
||||
### `fix-constructors` - Fix Java Constructors
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-d, --directory` | Directory to scan (default: ./app) |
|
||||
|
||||
### `analyze` - Analyze Project Structure
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-b, --base-dir` | Base directory (default: .) |
|
||||
| `-o, --output` | Output JSON file |
|
||||
|
||||
### `gui` - Launch GUI
|
||||
|
||||
No options. Launches the PyQt6 registration GUI.
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Quick Test Key Generation
|
||||
```bash
|
||||
./tustu_tools.py gen-key --test-data
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
Generated test data:
|
||||
First Name: James
|
||||
Last Name: Smith
|
||||
Email: james.smith@gmail.com
|
||||
Product: MegaLogViewer
|
||||
Secret: secret123
|
||||
Serial: SN001
|
||||
|
||||
Registration Key (5param):
|
||||
ABCD1234EFGH5678WXYZ
|
||||
```
|
||||
|
||||
### Example 2: Generate Email-Ready Keys
|
||||
```bash
|
||||
./tustu_tools.py gen-key --test-data --email-format
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
Generated test data:
|
||||
First Name: Mary
|
||||
Last Name: Johnson
|
||||
Email: mary.johnson@yahoo.com
|
||||
Product: TunerStudio
|
||||
Secret: testkey
|
||||
Serial: ABC123
|
||||
|
||||
Registration Key (5param):
|
||||
XYZ9876MNOP5432QRST
|
||||
|
||||
Email Format:
|
||||
[Registration]
|
||||
First Name: Mary
|
||||
Last Name: Johnson
|
||||
Registered email: mary.johnson@yahoo.com
|
||||
Serial Number: ABC123
|
||||
Registration Key: XYZ9876MNOP5432QRST
|
||||
[End Registration]
|
||||
```
|
||||
|
||||
### Example 3: Batch Test Data Generation
|
||||
```bash
|
||||
./tustu_tools.py test-data -n 10 --email-format > test_keys.txt
|
||||
```
|
||||
|
||||
### Example 4: Project Analysis
|
||||
```bash
|
||||
./tustu_tools.py analyze -o structure.json
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
======================================================================
|
||||
STRUCTURE ANALYSIS
|
||||
======================================================================
|
||||
Total Java files: 1247
|
||||
Unique packages: 89
|
||||
Package mismatches: 342
|
||||
|
||||
Package breakdown:
|
||||
Obfuscated (1-2 letters): 26
|
||||
Proper (com.*, org.*): 63
|
||||
|
||||
Analysis saved to: structure.json
|
||||
```
|
||||
|
||||
### Example 5: Fix All Constructors
|
||||
```bash
|
||||
./tustu_tools.py fix-constructors -d ./app
|
||||
```
|
||||
|
||||
Output:
|
||||
```
|
||||
Scanning for Java files in: ./app
|
||||
Fixed: ./app/A/File1.java:42 - A -> ClassNameA
|
||||
Fixed: ./app/B/File2.java:15 - B -> ClassNameB
|
||||
|
||||
✅ Fixed 23 files
|
||||
```
|
||||
|
||||
## Migration from Individual Scripts
|
||||
|
||||
The unified tool replaces multiple individual scripts with a single command interface:
|
||||
|
||||
| Old Command | New Command |
|
||||
|-------------|-------------|
|
||||
| `python3 registration_gui.py` | `./tustu-tools gui` |
|
||||
| `python3 test_dummy_data.py` | `./tustu-tools test-data` |
|
||||
| `python3 test_email_generation.py` | `./tustu-tools gen-key --email-format` |
|
||||
| `python3 fix_constructors.py` | `./tustu-tools fix-constructors` |
|
||||
| `python3 reorganize_structure.py` | `./tustu-tools analyze` |
|
||||
|
||||
**Legacy scripts** are preserved in `legacy/` folder for reference.
|
||||
|
||||
## Benefits
|
||||
|
||||
| Benefit | Description |
|
||||
|---------|-------------|
|
||||
| **Unified Interface** | Single tool instead of multiple scripts |
|
||||
| **Consistent CLI** | All commands use argparse with `--help` |
|
||||
| **Better Discoverability** | Easy to find features via help text |
|
||||
| **Less Clutter** | One script instead of 8+ files |
|
||||
| **Easy to Extend** | Add new commands as needed |
|
||||
|
||||
## Legacy Scripts
|
||||
|
||||
Original scripts are preserved in the `legacy/` folder:
|
||||
|
||||
- **`registration_gui.py`** - Full PyQt6 GUI (still usable directly)
|
||||
- **Other scripts** - Kept for reference or standalone use
|
||||
|
||||
To use legacy scripts:
|
||||
|
||||
```bash
|
||||
python3 legacy/registration_gui.py # Direct GUI launch
|
||||
python3 legacy/test_dummy_data.py # Legacy test data script
|
||||
```
|
||||
|
||||
## Help & Support
|
||||
|
||||
Get detailed help for any command:
|
||||
|
||||
```bash
|
||||
./tustu-tools --help # List all commands
|
||||
./tustu-tools gen-key --help # Key generation options
|
||||
./tustu-tools test-data --help # Test data options
|
||||
./tustu-tools fix-constructors --help # Constructor fix options
|
||||
./tustu-tools analyze --help # Analysis options
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
To add a new command to the tool:
|
||||
|
||||
1. Add a new subparser in the `main()` function
|
||||
2. Create a `cmd_<name>(args)` handler function
|
||||
3. Add dispatch logic to connect command to handler
|
||||
|
||||
See `tustu_tools.py` source for examples.
|
||||
74
scripts/data/README.md
Normal file
74
scripts/data/README.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Data Files
|
||||
|
||||
This folder contains JSON data files generated by analysis and mapping scripts.
|
||||
|
||||
## Files
|
||||
|
||||
### COMPLETE_RENAME_MAPPING.json
|
||||
**Source:** `rename_obfuscated_files.py` (legacy)
|
||||
**Purpose:** Complete mapping for renaming obfuscated Java files
|
||||
**Contains:**
|
||||
- File rename mappings (old path → new path)
|
||||
- Obfuscated class map
|
||||
- Import dependencies
|
||||
- Files requiring updates
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
# Generated via legacy script, can be used for reference
|
||||
python3 ../legacy/rename_obfuscated_files.py --execute
|
||||
```
|
||||
|
||||
### JAVA_ANALYSIS_RESULTS.json
|
||||
**Source:** Java analysis scripts
|
||||
**Purpose:** Results from analyzing Java codebase
|
||||
**Contains:**
|
||||
- Class information
|
||||
- Package structure
|
||||
- Code metrics
|
||||
|
||||
### PACKAGE_MAPPING.json
|
||||
**Source:** Package reorganization scripts
|
||||
**Purpose:** Mapping of package names and structure
|
||||
**Contains:**
|
||||
- Package declarations
|
||||
- Directory structure
|
||||
- Mismatches between declared and actual locations
|
||||
|
||||
### STRUCTURE_ANALYSIS.json
|
||||
**Source:** `tustu_tools.py analyze` or `reorganize_structure.py`
|
||||
**Purpose:** Project structure analysis results
|
||||
**Contains:**
|
||||
- Total file counts
|
||||
- Package statistics
|
||||
- Mismatched files
|
||||
- Obfuscated vs proper packages
|
||||
|
||||
**Generate new analysis:**
|
||||
```bash
|
||||
cd ..
|
||||
python3 tustu_tools.py analyze -o data/STRUCTURE_ANALYSIS.json
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
These files are primarily for reference and analysis purposes. They document:
|
||||
- Historical code structure
|
||||
- Transformation mappings
|
||||
- Analysis results
|
||||
|
||||
Most can be regenerated using `tustu_tools.py` commands if needed.
|
||||
|
||||
## Updating
|
||||
|
||||
To regenerate structure analysis:
|
||||
```bash
|
||||
cd /path/to/tustu
|
||||
./tustu-tools analyze -o scripts/data/STRUCTURE_ANALYSIS.json
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- These files are typically **not** committed to version control (large, generated data)
|
||||
- They serve as snapshots of analysis at specific points in time
|
||||
- Useful for understanding code transformations and refactoring decisions
|
||||
72
scripts/legacy/README.md
Normal file
72
scripts/legacy/README.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Legacy Scripts
|
||||
|
||||
This folder contains the original individual scripts that have been merged into the unified `tustu_tools.py` tool.
|
||||
|
||||
## Purpose
|
||||
|
||||
These scripts are preserved for:
|
||||
- **Reference** - Understanding the original implementation
|
||||
- **Historical documentation** - Tracking how the code evolved
|
||||
- **Backup** - In case specific functionality needs to be extracted
|
||||
- **Standalone use** - Some scripts may still work independently
|
||||
|
||||
## Recommendation
|
||||
|
||||
**Use `../tustu_tools.py` instead** - It provides all functionality from these scripts through a unified command-line interface.
|
||||
|
||||
## Legacy Scripts
|
||||
|
||||
| Script | Status | Replacement |
|
||||
|--------|--------|-------------|
|
||||
| `registration_gui.py` | ✅ Still functional standalone | `tustu_tools.py gui` |
|
||||
| `demo_test_data_ui.py` | ⚠️ Demo only | Integrated into all commands |
|
||||
| `test_dummy_data.py` | ⚠️ Superseded | `tustu_tools.py test-data` |
|
||||
| `test_email_generation.py` | ⚠️ Superseded | `tustu_tools.py gen-key --email-format` |
|
||||
| `fix_constructors.py` | ⚠️ Superseded | `tustu_tools.py fix-constructors` |
|
||||
| `fix_constructors_v2.py` | ⚠️ Superseded | `tustu_tools.py fix-constructors` |
|
||||
| `reorganize_structure.py` | ⚠️ Superseded | `tustu_tools.py analyze` |
|
||||
| `rename_obfuscated_files.py` | ⚠️ Partial | Core utilities in tustu_tools.py |
|
||||
|
||||
## Notes
|
||||
|
||||
### registration_gui.py
|
||||
The full PyQt6 GUI is still functional and can be run standalone:
|
||||
```bash
|
||||
python3 registration_gui.py
|
||||
```
|
||||
|
||||
However, you can also launch it via:
|
||||
```bash
|
||||
python3 ../tustu_tools.py gui
|
||||
```
|
||||
|
||||
### Other Scripts
|
||||
Most other scripts have been fully integrated into the unified tool and should not be run directly anymore.
|
||||
|
||||
## Migration
|
||||
|
||||
If you have scripts or tools that reference these files, update them to use `tustu_tools.py`:
|
||||
|
||||
**Before:**
|
||||
```bash
|
||||
python3 scripts/test_dummy_data.py
|
||||
python3 scripts/fix_constructors.py
|
||||
```
|
||||
|
||||
**After:**
|
||||
```bash
|
||||
python3 scripts/tustu_tools.py test-data
|
||||
python3 scripts/tustu_tools.py fix-constructors
|
||||
```
|
||||
|
||||
Or from project root:
|
||||
```bash
|
||||
./tustu-tools test-data
|
||||
./tustu-tools fix-constructors
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
See the parent folder's documentation:
|
||||
- `../TUSTU_TOOLS_README.md` - Complete unified tool documentation
|
||||
- `../README_SCRIPTS.md` - Scripts folder overview
|
||||
628
scripts/tustu_tools.py
Executable file
628
scripts/tustu_tools.py
Executable file
@@ -0,0 +1,628 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
TuStu Tools - Unified command-line utility
|
||||
Combines all scripts from the scripts folder into a single argparse-based tool.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import shutil
|
||||
import random
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
import argparse
|
||||
|
||||
# ============================================================================
|
||||
# REGISTRATION KEY GENERATION (from registration_gui.py)
|
||||
# ============================================================================
|
||||
|
||||
class DummyDataGenerator:
|
||||
"""Generate realistic test data for registration"""
|
||||
|
||||
FIRST_NAMES = [
|
||||
"James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph",
|
||||
"Mary", "Patricia", "Jennifer", "Linda", "Barbara", "Elizabeth", "Susan", "Jessica",
|
||||
"Thomas", "Charles", "Christopher", "Daniel", "Matthew", "Anthony", "Mark", "Donald",
|
||||
"Nancy", "Karen", "Betty", "Helen", "Sandra", "Donna", "Carol", "Ruth"
|
||||
]
|
||||
|
||||
LAST_NAMES = [
|
||||
"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis",
|
||||
"Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez", "Wilson", "Anderson", "Thomas",
|
||||
"Taylor", "Moore", "Jackson", "Martin", "Lee", "Thompson", "White", "Harris",
|
||||
"Clark", "Lewis", "Robinson", "Walker", "Young", "Allen", "King", "Wright"
|
||||
]
|
||||
|
||||
DOMAINS = [
|
||||
"gmail.com", "yahoo.com", "outlook.com", "hotmail.com", "icloud.com",
|
||||
"company.com", "business.net", "enterprise.org", "tech.io", "example.com"
|
||||
]
|
||||
|
||||
PRODUCTS = ["MegaLogViewer", "TunerStudio", "DataLogger"]
|
||||
SECRETS = ["secret123", "testkey", "demo2024", "abc123xyz"]
|
||||
SERIALS = ["SN001", "SN002", "ABC123", "XYZ789", "DEV001", "TEST99"]
|
||||
|
||||
@staticmethod
|
||||
def generate():
|
||||
"""Generate a complete set of dummy registration data"""
|
||||
first_name = random.choice(DummyDataGenerator.FIRST_NAMES)
|
||||
last_name = random.choice(DummyDataGenerator.LAST_NAMES)
|
||||
email = f"{first_name.lower()}.{last_name.lower()}@{random.choice(DummyDataGenerator.DOMAINS)}"
|
||||
product = random.choice(DummyDataGenerator.PRODUCTS)
|
||||
secret = random.choice(DummyDataGenerator.SECRETS)
|
||||
serial = random.choice(DummyDataGenerator.SERIALS)
|
||||
|
||||
return {
|
||||
'first_name': first_name,
|
||||
'last_name': last_name,
|
||||
'email': email,
|
||||
'product': product,
|
||||
'secret': secret,
|
||||
'serial': serial
|
||||
}
|
||||
|
||||
|
||||
class RegistrationKeyGenerator:
|
||||
"""Implementation of the registration key generation algorithm"""
|
||||
|
||||
CHARSET_BASIC = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ"
|
||||
CHARSET_ENHANCED = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"
|
||||
SPECIAL_CHARS = {96, 92, 91, 93, 59, 46} # `, \, [, ], ;, .
|
||||
|
||||
@staticmethod
|
||||
def obfuscate(first_name, last_name, product_name, email):
|
||||
"""Basic obfuscation algorithm (Method 1)"""
|
||||
if not all([first_name, last_name, product_name, email]):
|
||||
return None
|
||||
|
||||
combined = last_name + product_name + first_name + last_name + email
|
||||
byte_array = bytearray(combined.encode('utf-8'))
|
||||
byte_array.reverse()
|
||||
|
||||
for i in range(len(byte_array)):
|
||||
b = byte_array[i]
|
||||
transformed = (b + ((b - 32) % 7)) - (i % 4)
|
||||
if transformed > 122:
|
||||
transformed -= 9
|
||||
byte_array[i] = transformed & 0xFF
|
||||
|
||||
for i in range(len(byte_array)):
|
||||
if byte_array[i] in RegistrationKeyGenerator.SPECIAL_CHARS:
|
||||
byte_array[i] = (byte_array[i] + 6 + (i % 10)) & 0xFF
|
||||
|
||||
return byte_array.decode('latin-1')
|
||||
|
||||
@staticmethod
|
||||
def generate_key_basic(first_name, last_name, product_name, email):
|
||||
"""Generate registration key (4 parameters - Method 1)"""
|
||||
return RegistrationKeyGenerator.obfuscate(first_name, last_name, product_name, email)
|
||||
|
||||
@staticmethod
|
||||
def generate_key_5param(first_name, last_name, product_name, secret, email):
|
||||
"""Generate registration key with secret (5 parameters - Method 2)"""
|
||||
if not all([first_name, last_name, product_name, secret, email]):
|
||||
return None
|
||||
|
||||
obfuscated = RegistrationKeyGenerator.obfuscate(first_name, last_name, product_name, email)
|
||||
if not obfuscated:
|
||||
return None
|
||||
|
||||
hash_input = (obfuscated + secret).encode('utf-8')
|
||||
md5 = hashlib.md5()
|
||||
md5.update(hash_input)
|
||||
md5.update(hash_input)
|
||||
md5.digest()
|
||||
md5.update(hash_input)
|
||||
hash_digest = md5.digest()
|
||||
|
||||
checksum_md5 = hashlib.md5(hash_digest)
|
||||
checksum = checksum_md5.digest()[:4]
|
||||
combined = checksum + hash_digest
|
||||
|
||||
key = ""
|
||||
for byte in combined:
|
||||
unsigned_byte = byte if byte >= 0 else byte + 256
|
||||
key += RegistrationKeyGenerator.CHARSET_BASIC[abs(unsigned_byte) % len(RegistrationKeyGenerator.CHARSET_BASIC)]
|
||||
|
||||
return key
|
||||
|
||||
@staticmethod
|
||||
def generate_key_7param(first_name, last_name, product_name, secret, email, field1, field2):
|
||||
"""Generate enhanced registration key (7 parameters - Method 3)"""
|
||||
if not all([first_name, last_name, product_name, secret, email, field1, field2]):
|
||||
return None
|
||||
|
||||
first_name = first_name.lower()
|
||||
last_name = last_name.lower()
|
||||
email = email.lower()
|
||||
|
||||
obfuscated = RegistrationKeyGenerator.obfuscate(first_name, last_name, product_name, email)
|
||||
if not obfuscated:
|
||||
return None
|
||||
|
||||
base_string = obfuscated + field1 + field2
|
||||
hash_input = (base_string + secret).encode('utf-8')
|
||||
|
||||
md5 = hashlib.md5()
|
||||
md5.update(hash_input)
|
||||
md5.update(hash_input)
|
||||
md5.update((hash_input.decode('utf-8') + field1).encode('utf-8'))
|
||||
hash_digest = md5.digest()
|
||||
|
||||
checksum_md5 = hashlib.md5(hash_digest)
|
||||
checksum = checksum_md5.digest()[:4]
|
||||
combined = checksum + hash_digest
|
||||
|
||||
key = ""
|
||||
for byte in combined:
|
||||
unsigned_byte = byte if byte >= 0 else byte + 256
|
||||
key += RegistrationKeyGenerator.CHARSET_ENHANCED[abs(unsigned_byte) % len(RegistrationKeyGenerator.CHARSET_ENHANCED)]
|
||||
|
||||
return key
|
||||
|
||||
@staticmethod
|
||||
def generate_key_8param(first_name, last_name, product_name, secret, email, field1, field2, field3):
|
||||
"""Generate full registration key (8 parameters - Method 4)"""
|
||||
if not all([first_name, last_name, product_name, secret, email, field1, field2, field3]):
|
||||
return None
|
||||
|
||||
first_name = first_name.lower()
|
||||
last_name = last_name.lower()
|
||||
email = email.lower()
|
||||
|
||||
obfuscated = RegistrationKeyGenerator.obfuscate(first_name, last_name, product_name, email)
|
||||
if not obfuscated:
|
||||
return None
|
||||
|
||||
base_string = obfuscated + field1 + field2 + field3
|
||||
hash_input = (base_string + secret).encode('utf-8')
|
||||
|
||||
md5 = hashlib.md5()
|
||||
md5.update(hash_input)
|
||||
md5.update(hash_input)
|
||||
md5.update((hash_input.decode('utf-8') + field1).encode('utf-8'))
|
||||
hash_digest = md5.digest()
|
||||
|
||||
checksum_md5 = hashlib.md5(hash_digest)
|
||||
checksum = checksum_md5.digest()[:4]
|
||||
combined = checksum + hash_digest
|
||||
|
||||
key = ""
|
||||
for byte in combined:
|
||||
unsigned_byte = byte if byte >= 0 else byte + 256
|
||||
key += RegistrationKeyGenerator.CHARSET_ENHANCED[abs(unsigned_byte) % len(RegistrationKeyGenerator.CHARSET_ENHANCED)]
|
||||
|
||||
return key
|
||||
|
||||
|
||||
def generate_registration_email(first_name, last_name, email, registration_key, serial_number=None):
|
||||
"""Generate a registration email in the format expected by MegaLogViewer"""
|
||||
email_format = "[Registration]\n"
|
||||
email_format += f"First Name: {first_name}\n"
|
||||
email_format += f"Last Name: {last_name}\n"
|
||||
email_format += f"Registered email: {email}\n"
|
||||
|
||||
if serial_number:
|
||||
email_format += f"Serial Number: {serial_number}\n"
|
||||
|
||||
email_format += f"Registration Key: {registration_key}\n"
|
||||
email_format += "[End Registration]"
|
||||
|
||||
return email_format
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# JAVA CONSTRUCTOR FIXING (from fix_constructors.py)
|
||||
# ============================================================================
|
||||
|
||||
def get_class_name_from_file(filepath):
|
||||
"""Extract the main class name from a Java file."""
|
||||
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
content = f.read()
|
||||
|
||||
match = re.search(r'\bclass\s+([A-Za-z_][A-Za-z0-9_]*)', content)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
|
||||
def fix_constructor_in_file(filepath, class_name):
|
||||
"""Fix constructor names in a file."""
|
||||
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
modified = False
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
match = re.match(r'^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*\([^)]*\)\s*\{\s*\}?\s*$', line)
|
||||
if match:
|
||||
indent = match.group(1)
|
||||
name = match.group(2)
|
||||
|
||||
if name in ['public', 'private', 'protected', 'static', 'final']:
|
||||
continue
|
||||
|
||||
if (len(name) <= 2 or name != class_name) and name[0].isupper():
|
||||
if i > 0:
|
||||
prev_line = lines[i-1].strip()
|
||||
if not re.search(r'\b(void|int|boolean|String|long|double|float|byte|short|char|public|private|protected)\s*$', prev_line):
|
||||
fixed_line = re.sub(r'^(\s*)' + re.escape(name), r'\1' + class_name, line)
|
||||
lines[i] = fixed_line
|
||||
modified = True
|
||||
print(f" Fixed: {filepath}:{i+1} - {name} -> {class_name}")
|
||||
|
||||
if modified:
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.writelines(lines)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# STRUCTURE REORGANIZATION (from reorganize_structure.py)
|
||||
# ============================================================================
|
||||
|
||||
def analyze_current_structure(base_dir):
|
||||
"""Analyze the current app directory structure"""
|
||||
app_dir = os.path.join(base_dir, 'app')
|
||||
|
||||
analysis = {
|
||||
'packages': defaultdict(list),
|
||||
'mismatches': [],
|
||||
'dependencies': defaultdict(set),
|
||||
'total_files': 0
|
||||
}
|
||||
|
||||
print("Analyzing current structure...")
|
||||
|
||||
for root, dirs, files in os.walk(app_dir):
|
||||
for file in files:
|
||||
if not file.endswith('.java'):
|
||||
continue
|
||||
|
||||
filepath = os.path.join(root, file)
|
||||
rel_path = os.path.relpath(filepath, base_dir)
|
||||
analysis['total_files'] += 1
|
||||
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
content = f.read()
|
||||
|
||||
pkg_match = re.search(r'package\s+([\w.]+);', content)
|
||||
if pkg_match:
|
||||
declared_pkg = pkg_match.group(1)
|
||||
analysis['packages'][declared_pkg].append(rel_path)
|
||||
|
||||
dir_path = os.path.dirname(rel_path).replace('app/', '')
|
||||
if dir_path.startswith('obfuscated_packages/'):
|
||||
expected_pkg = dir_path.replace('obfuscated_packages/', '').replace(os.sep, '.')
|
||||
else:
|
||||
expected_pkg = dir_path.replace(os.sep, '.')
|
||||
|
||||
if declared_pkg != expected_pkg and expected_pkg != '.':
|
||||
analysis['mismatches'].append({
|
||||
'file': rel_path,
|
||||
'declared': declared_pkg,
|
||||
'location': expected_pkg
|
||||
})
|
||||
|
||||
imports = re.findall(r'import\s+([\w.]+);', content)
|
||||
if pkg_match:
|
||||
for imp in imports:
|
||||
imp_pkg = '.'.join(imp.split('.')[:-1])
|
||||
if imp_pkg:
|
||||
analysis['dependencies'][declared_pkg].add(imp_pkg)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
return analysis
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# FILE RENAMING (from rename_obfuscated_files.py)
|
||||
# ============================================================================
|
||||
|
||||
def extract_class_info(filepath, content):
|
||||
"""Extract comprehensive information about a Java class"""
|
||||
info = {
|
||||
'filepath': filepath,
|
||||
'class_name': None,
|
||||
'is_interface': False,
|
||||
'is_enum': False,
|
||||
'extends': None,
|
||||
'implements': [],
|
||||
'key_methods': [],
|
||||
'field_types': []
|
||||
}
|
||||
|
||||
class_match = re.search(r'(?:public\s+)?(?:abstract\s+)?(?:final\s+)?(class|interface|enum)\s+(\w+)', content)
|
||||
if class_match:
|
||||
info['class_name'] = class_match.group(2)
|
||||
info['is_interface'] = class_match.group(1) == 'interface'
|
||||
info['is_enum'] = class_match.group(1) == 'enum'
|
||||
|
||||
extends_match = re.search(r'extends\s+([\w.]+)', content)
|
||||
if extends_match:
|
||||
info['extends'] = extends_match.group(1).split('.')[-1]
|
||||
|
||||
implements_matches = re.findall(r'implements\s+([\w.,\s]+)', content)
|
||||
for impl_str in implements_matches:
|
||||
interfaces = [i.strip() for i in impl_str.split(',')]
|
||||
info['implements'].extend(interfaces)
|
||||
|
||||
methods = re.findall(r'(?:public|private|protected)\s+(?:static\s+)?(?:\w+\s+)?(\w+)\s*\(', content)
|
||||
info['key_methods'] = [m for m in methods if len(m) > 2 and m not in ['get', 'set', 'is']][:10]
|
||||
|
||||
fields = re.findall(r'(?:private|protected|public)\s+(?:static\s+)?(?:final\s+)?(\w+)\s+(\w+)\s*[;=]', content)
|
||||
java_primitives = ['int', 'long', 'boolean', 'double', 'float', 'String', 'List', 'Map', 'Object']
|
||||
info['field_types'] = [f[0] for f in fields if len(f[0]) > 2 and f[0] not in java_primitives][:5]
|
||||
|
||||
return info
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# COMMAND HANDLERS
|
||||
# ============================================================================
|
||||
|
||||
def cmd_generate_key(args):
|
||||
"""Generate a registration key"""
|
||||
data = None
|
||||
|
||||
if args.test_data:
|
||||
data = DummyDataGenerator.generate()
|
||||
print("Generated test data:")
|
||||
print(f" First Name: {data['first_name']}")
|
||||
print(f" Last Name: {data['last_name']}")
|
||||
print(f" Email: {data['email']}")
|
||||
print(f" Product: {data['product']}")
|
||||
print(f" Secret: {data['secret']}")
|
||||
print(f" Serial: {data['serial']}")
|
||||
print()
|
||||
else:
|
||||
data = {
|
||||
'first_name': args.first_name,
|
||||
'last_name': args.last_name,
|
||||
'email': args.email,
|
||||
'product': args.product,
|
||||
'secret': args.secret,
|
||||
'serial': args.serial
|
||||
}
|
||||
|
||||
# Generate key based on algorithm
|
||||
key = None
|
||||
if args.algorithm == '4param':
|
||||
key = RegistrationKeyGenerator.generate_key_basic(
|
||||
data['first_name'], data['last_name'], data['product'], data['email']
|
||||
)
|
||||
elif args.algorithm == '5param':
|
||||
key = RegistrationKeyGenerator.generate_key_5param(
|
||||
data['first_name'], data['last_name'], data['product'],
|
||||
data['secret'], data['email']
|
||||
)
|
||||
elif args.algorithm == '7param':
|
||||
key = RegistrationKeyGenerator.generate_key_7param(
|
||||
data['first_name'], data['last_name'], data['product'],
|
||||
data['secret'], data['email'], args.field1 or '01', args.field2 or '2015'
|
||||
)
|
||||
elif args.algorithm == '8param':
|
||||
key = RegistrationKeyGenerator.generate_key_8param(
|
||||
data['first_name'], data['last_name'], data['product'],
|
||||
data['secret'], data['email'], args.field1 or '01',
|
||||
args.field2 or '2015', data['serial']
|
||||
)
|
||||
|
||||
if key:
|
||||
print(f"Registration Key ({args.algorithm}):")
|
||||
print(f" {key}")
|
||||
print()
|
||||
|
||||
if args.email_format:
|
||||
email = generate_registration_email(
|
||||
data['first_name'], data['last_name'], data['email'],
|
||||
key, data.get('serial')
|
||||
)
|
||||
print("Email Format:")
|
||||
print(email)
|
||||
else:
|
||||
print("Error: Failed to generate key. Check your inputs.")
|
||||
|
||||
|
||||
def cmd_generate_test_data(args):
|
||||
"""Generate multiple test data sets"""
|
||||
print(f"Generating {args.count} test data sets:")
|
||||
print("=" * 80)
|
||||
|
||||
for i in range(args.count):
|
||||
data = DummyDataGenerator.generate()
|
||||
key = RegistrationKeyGenerator.generate_key_5param(
|
||||
data['first_name'], data['last_name'], data['product'],
|
||||
data['secret'], data['email']
|
||||
)
|
||||
|
||||
print(f"\nTest Set {i+1}:")
|
||||
print(f" Name: {data['first_name']} {data['last_name']}")
|
||||
print(f" Email: {data['email']}")
|
||||
print(f" Product: {data['product']}")
|
||||
print(f" Secret: {data['secret']}")
|
||||
print(f" Serial: {data['serial']}")
|
||||
print(f" Key: {key}")
|
||||
|
||||
if args.email_format:
|
||||
print()
|
||||
email = generate_registration_email(
|
||||
data['first_name'], data['last_name'], data['email'],
|
||||
key, data['serial']
|
||||
)
|
||||
print(email)
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
|
||||
|
||||
def cmd_fix_constructors(args):
|
||||
"""Fix misnamed constructors in Java files"""
|
||||
app_dir = Path(args.directory)
|
||||
|
||||
if not app_dir.exists():
|
||||
print(f"Error: Directory not found: {app_dir}")
|
||||
return
|
||||
|
||||
print(f"Scanning for Java files in: {app_dir}")
|
||||
fixed_files = 0
|
||||
|
||||
for java_file in app_dir.rglob('*.java'):
|
||||
class_name = get_class_name_from_file(java_file)
|
||||
if class_name and fix_constructor_in_file(java_file, class_name):
|
||||
fixed_files += 1
|
||||
|
||||
print(f"\n✅ Fixed {fixed_files} files")
|
||||
|
||||
|
||||
def cmd_analyze_structure(args):
|
||||
"""Analyze the project structure"""
|
||||
base_dir = args.base_dir
|
||||
analysis = analyze_current_structure(base_dir)
|
||||
|
||||
print(f"\n{'='*70}")
|
||||
print("STRUCTURE ANALYSIS")
|
||||
print(f"{'='*70}")
|
||||
print(f"Total Java files: {analysis['total_files']}")
|
||||
print(f"Unique packages: {len(analysis['packages'])}")
|
||||
print(f"Package mismatches: {len(analysis['mismatches'])}")
|
||||
|
||||
obfuscated_pkgs = [p for p in analysis['packages'].keys() if len(p) <= 2 and p.isalpha()]
|
||||
proper_pkgs = [p for p in analysis['packages'].keys() if p.startswith('com.') or p.startswith('org.')]
|
||||
|
||||
print(f"\nPackage breakdown:")
|
||||
print(f" Obfuscated (1-2 letters): {len(obfuscated_pkgs)}")
|
||||
print(f" Proper (com.*, org.*): {len(proper_pkgs)}")
|
||||
|
||||
if args.output:
|
||||
output = {
|
||||
'total_files': analysis['total_files'],
|
||||
'packages': {k: len(v) for k, v in analysis['packages'].items()},
|
||||
'mismatches': len(analysis['mismatches']),
|
||||
'sample_mismatches': analysis['mismatches'][:20]
|
||||
}
|
||||
|
||||
with open(args.output, 'w') as f:
|
||||
json.dump(output, f, indent=2)
|
||||
print(f"\nAnalysis saved to: {args.output}")
|
||||
|
||||
|
||||
def cmd_launch_gui(args):
|
||||
"""Launch the registration GUI"""
|
||||
try:
|
||||
# Import from legacy folder
|
||||
import sys
|
||||
from pathlib import Path
|
||||
legacy_path = Path(__file__).parent / 'legacy'
|
||||
sys.path.insert(0, str(legacy_path))
|
||||
from registration_gui import main as gui_main
|
||||
gui_main()
|
||||
except ImportError as e:
|
||||
if 'PyQt6' in str(e):
|
||||
print("Error: PyQt6 not installed. Install with: pip install PyQt6")
|
||||
else:
|
||||
print(f"Error: Could not import registration_gui: {e}")
|
||||
except Exception as e:
|
||||
print(f"Error launching GUI: {e}")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# MAIN
|
||||
# ============================================================================
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='TuStu Tools - Unified command-line utility for TunerStudio project',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
# Generate test data with valid keys
|
||||
%(prog)s test-data -n 5
|
||||
|
||||
# Generate a registration key with test data
|
||||
%(prog)s gen-key --test-data --algorithm 5param
|
||||
|
||||
# Generate key with specific parameters
|
||||
%(prog)s gen-key -f John -l Doe -e john@example.com -p MegaLogViewer -s secret123
|
||||
|
||||
# Fix Java constructors
|
||||
%(prog)s fix-constructors -d ./app
|
||||
|
||||
# Analyze project structure
|
||||
%(prog)s analyze -o structure_report.json
|
||||
|
||||
# Launch GUI
|
||||
%(prog)s gui
|
||||
"""
|
||||
)
|
||||
|
||||
subparsers = parser.add_subparsers(dest='command', help='Available commands')
|
||||
|
||||
# Generate key command
|
||||
gen_key_parser = subparsers.add_parser('gen-key', help='Generate registration key')
|
||||
gen_key_parser.add_argument('-f', '--first-name', help='First name')
|
||||
gen_key_parser.add_argument('-l', '--last-name', help='Last name')
|
||||
gen_key_parser.add_argument('-e', '--email', help='Email address')
|
||||
gen_key_parser.add_argument('-p', '--product', help='Product name')
|
||||
gen_key_parser.add_argument('-s', '--secret', help='Secret key')
|
||||
gen_key_parser.add_argument('--serial', help='Serial number')
|
||||
gen_key_parser.add_argument('-a', '--algorithm',
|
||||
choices=['4param', '5param', '7param', '8param'],
|
||||
default='5param', help='Key generation algorithm')
|
||||
gen_key_parser.add_argument('--field1', help='Additional field 1 (for 7/8 param)')
|
||||
gen_key_parser.add_argument('--field2', help='Additional field 2 (for 7/8 param)')
|
||||
gen_key_parser.add_argument('-t', '--test-data', action='store_true',
|
||||
help='Generate random test data')
|
||||
gen_key_parser.add_argument('--email-format', action='store_true',
|
||||
help='Output in email format')
|
||||
|
||||
# Test data command
|
||||
test_data_parser = subparsers.add_parser('test-data', help='Generate test data sets')
|
||||
test_data_parser.add_argument('-n', '--count', type=int, default=5,
|
||||
help='Number of test data sets to generate')
|
||||
test_data_parser.add_argument('--email-format', action='store_true',
|
||||
help='Output in email format')
|
||||
|
||||
# Fix constructors command
|
||||
fix_parser = subparsers.add_parser('fix-constructors',
|
||||
help='Fix misnamed Java constructors')
|
||||
fix_parser.add_argument('-d', '--directory', default='./app',
|
||||
help='Directory to scan for Java files')
|
||||
|
||||
# Analyze structure command
|
||||
analyze_parser = subparsers.add_parser('analyze',
|
||||
help='Analyze project structure')
|
||||
analyze_parser.add_argument('-b', '--base-dir', default='.',
|
||||
help='Base directory of the project')
|
||||
analyze_parser.add_argument('-o', '--output',
|
||||
help='Output file for analysis results (JSON)')
|
||||
|
||||
# GUI command
|
||||
gui_parser = subparsers.add_parser('gui', help='Launch registration GUI')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
# Execute command
|
||||
if args.command == 'gen-key':
|
||||
cmd_generate_key(args)
|
||||
elif args.command == 'test-data':
|
||||
cmd_generate_test_data(args)
|
||||
elif args.command == 'fix-constructors':
|
||||
cmd_fix_constructors(args)
|
||||
elif args.command == 'analyze':
|
||||
cmd_analyze_structure(args)
|
||||
elif args.command == 'gui':
|
||||
cmd_launch_gui(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
4
tustu-tools
Executable file
4
tustu-tools
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
# Wrapper script to call tustu_tools.py from anywhere in the project
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
python3 "$SCRIPT_DIR/scripts/tustu_tools.py" "$@"
|
||||
Reference in New Issue
Block a user