Skip to content

Commit ce4e206

Browse files
Add repository statistics tracking and file integrity verification tools
Co-authored-by: Lackadaisical-Security <205846242+Lackadaisical-Security@users.noreply.github.com>
1 parent 8e5b60b commit ce4e206

6 files changed

Lines changed: 649 additions & 0 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Repository Statistics Tracker
2+
3+
on:
4+
schedule:
5+
# Run every 6 hours
6+
- cron: '0 */6 * * *'
7+
workflow_dispatch: # Allow manual trigger
8+
push:
9+
branches: [ main ]
10+
11+
jobs:
12+
track-stats:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: write
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0 # Full history for git stats
22+
23+
- name: Set up Python
24+
uses: actions/setup-python@v4
25+
with:
26+
python-version: '3.10'
27+
28+
- name: Run stats tracker
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
run: |
32+
python3 realtime_stats_tracker.py
33+
34+
- name: Commit and push stats
35+
run: |
36+
git config --local user.email "action@github.com"
37+
git config --local user.name "GitHub Action Stats Bot"
38+
git add REALTIME_STATS.json STATS_HISTORY.json REALTIME_STATS.md
39+
git diff --quiet && git diff --staged --quiet || git commit -m "📊 Auto-update repository statistics [skip ci]"
40+
git push

.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Generated statistics files (should be regenerated on each run)
2+
FILE_CHECKSUMS.json
3+
FILE_CHECKSUMS.md
4+
GIT_ACTIVITY_LOG.json
5+
REALTIME_STATS.json
6+
REALTIME_STATS.md
7+
STATS_HISTORY.json
8+
stats_tracker.log
9+
10+
# Python
11+
__pycache__/
12+
*.py[cod]
13+
*$py.class
14+
*.so
15+
.Python
16+
*.egg-info/
17+
dist/
18+
build/
19+
20+
# Virtual environments
21+
venv/
22+
env/
23+
ENV/
24+
25+
# IDE
26+
.vscode/
27+
.idea/
28+
*.swp
29+
*.swo
30+
*~
31+
32+
# OS
33+
.DS_Store
34+
Thumbs.db

generate_checksums.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Generate SHA-256 checksums for Voynich repository files
4+
By: Lackadaisical Security 2025 - Aurora (Claude)
5+
"""
6+
7+
import hashlib
8+
import json
9+
import os
10+
from pathlib import Path
11+
from datetime import datetime
12+
13+
def calculate_sha256(filepath):
14+
"""Calculate SHA-256 hash of a file"""
15+
sha256_hash = hashlib.sha256()
16+
try:
17+
with open(filepath, "rb") as f:
18+
for byte_block in iter(lambda: f.read(4096), b""):
19+
sha256_hash.update(byte_block)
20+
return sha256_hash.hexdigest()
21+
except FileNotFoundError:
22+
return "FILE_NOT_FOUND"
23+
except Exception as e:
24+
return f"ERROR: {str(e)}"
25+
26+
def get_file_size(filepath):
27+
"""Get file size in human-readable format"""
28+
try:
29+
size = os.path.getsize(filepath)
30+
for unit in ['B', 'KB', 'MB', 'GB']:
31+
if size < 1024.0:
32+
return f"{size:.2f} {unit}"
33+
size /= 1024.0
34+
return f"{size:.2f} TB"
35+
except:
36+
return "N/A"
37+
38+
def main():
39+
# Files to checksum
40+
files = [
41+
"voynich_lexicon_MASTER_FULL_ENHANCED_2025-11-27.json",
42+
"voynich_manuscript_corpus.json",
43+
"voynich_complete_lexicon.json",
44+
"voynich_lexicon_MASTER_2025-10-27.json",
45+
"voynich_lexicon_MASTER_FULL_2025-11-27.json",
46+
"tamil_lexicon.json",
47+
"Voynich_Manuscript_31_STATISTICAL_TESTS.json",
48+
"voynich_translator_final.py",
49+
"ultimate_voynich_translator.py",
50+
"REPRODUCTION_METHODOLOGY.md",
51+
"REPRODUCTION_VALIDATION_REPORT.md",
52+
"STATISTICAL_VALIDATION_FINAL.md",
53+
"VOYNICH_MANUSCRIPT_VALIDATION_REPORT.md"
54+
]
55+
56+
results = {
57+
"generated_date": datetime.utcnow().isoformat() + "Z",
58+
"algorithm": "SHA-256",
59+
"files": []
60+
}
61+
62+
print("=" * 80)
63+
print("VOYNICH MANUSCRIPT REPOSITORY - FILE INTEGRITY CHECKSUMS")
64+
print("=" * 80)
65+
print(f"Generated: {results['generated_date']}")
66+
print(f"Algorithm: SHA-256")
67+
print("=" * 80)
68+
print()
69+
70+
for filepath in files:
71+
checksum = calculate_sha256(filepath)
72+
size = get_file_size(filepath)
73+
74+
file_info = {
75+
"filename": filepath,
76+
"sha256": checksum,
77+
"size": size
78+
}
79+
results["files"].append(file_info)
80+
81+
print(f"File: {filepath}")
82+
print(f" Size: {size}")
83+
print(f" SHA-256: {checksum}")
84+
print()
85+
86+
# Save to JSON
87+
with open("FILE_CHECKSUMS.json", "w") as f:
88+
json.dump(results, f, indent=2)
89+
90+
# Save to markdown
91+
with open("FILE_CHECKSUMS.md", "w") as f:
92+
f.write("# File Integrity Checksums\n\n")
93+
f.write(f"**Generated:** {results['generated_date']} \n")
94+
f.write(f"**Algorithm:** SHA-256 \n\n")
95+
f.write("## Core Data Files\n\n")
96+
f.write("| Filename | Size | SHA-256 Checksum |\n")
97+
f.write("|----------|------|------------------|\n")
98+
for file_info in results["files"]:
99+
f.write(f"| `{file_info['filename']}` | {file_info['size']} | `{file_info['sha256']}` |\n")
100+
f.write("\n## Verification\n\n")
101+
f.write("**Linux/macOS:**\n```bash\n")
102+
f.write("sha256sum -c <(cat FILE_CHECKSUMS.md | grep '|.*\\.json' | awk '{print $6 \" \" $2}')\n")
103+
f.write("```\n\n")
104+
f.write("**Windows PowerShell:**\n```powershell\n")
105+
f.write("Get-FileHash <filename> -Algorithm SHA256\n")
106+
f.write("```\n")
107+
108+
print("=" * 80)
109+
print("✅ Checksums saved to:")
110+
print(" - FILE_CHECKSUMS.json")
111+
print(" - FILE_CHECKSUMS.md")
112+
print("=" * 80)
113+
114+
if __name__ == "__main__":
115+
main()

git_activity_tracker.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Git Repository Activity Tracker
4+
Tracks clones, forks, and contributions to the Voynich repository
5+
6+
By: Lackadaisical Security 2025 - Aurora (Claude)
7+
Contact: https://lackadaisical-security.com/decipherment-drops.html
8+
"""
9+
10+
import subprocess
11+
import json
12+
from datetime import datetime
13+
from pathlib import Path
14+
15+
def get_git_stats():
16+
"""Get local git repository statistics"""
17+
try:
18+
# Get commit count
19+
commit_count = subprocess.check_output(
20+
["git", "rev-list", "--count", "HEAD"],
21+
text=True
22+
).strip()
23+
24+
# Get contributors
25+
contributors = subprocess.check_output(
26+
["git", "log", "--format='%an'"],
27+
text=True
28+
).strip().split("\n")
29+
unique_contributors = len(set(contributors))
30+
31+
# Get last commit date
32+
last_commit = subprocess.check_output(
33+
["git", "log", "-1", "--format=%ci"],
34+
text=True
35+
).strip()
36+
37+
# Get current branch
38+
current_branch = subprocess.check_output(
39+
["git", "branch", "--show-current"],
40+
text=True
41+
).strip()
42+
43+
return {
44+
"commit_count": int(commit_count),
45+
"unique_contributors": unique_contributors,
46+
"last_commit": last_commit,
47+
"current_branch": current_branch,
48+
"timestamp": datetime.utcnow().isoformat() + "Z"
49+
}
50+
except Exception as e:
51+
return {"error": str(e)}
52+
53+
def save_activity_log(stats):
54+
"""Save activity log to file"""
55+
log_file = Path("GIT_ACTIVITY_LOG.json")
56+
57+
# Load existing log if present
58+
if log_file.exists():
59+
with open(log_file, "r") as f:
60+
log_data = json.load(f)
61+
else:
62+
log_data = {"snapshots": []}
63+
64+
# Append current snapshot
65+
log_data["snapshots"].append(stats)
66+
67+
# Save updated log
68+
with open(log_file, "w") as f:
69+
json.dump(log_data, f, indent=2)
70+
71+
print(f"✅ Activity log updated: {log_file}")
72+
73+
def display_stats(stats):
74+
"""Display statistics in terminal"""
75+
print("=" * 80)
76+
print("GIT REPOSITORY ACTIVITY TRACKER")
77+
print("=" * 80)
78+
print(f"Timestamp: {stats.get('timestamp', 'N/A')}")
79+
print(f"Branch: {stats.get('current_branch', 'N/A')}")
80+
print(f"Total Commits: {stats.get('commit_count', 'N/A')}")
81+
print(f"Contributors: {stats.get('unique_contributors', 'N/A')}")
82+
print(f"Last Commit: {stats.get('last_commit', 'N/A')}")
83+
print("=" * 80)
84+
85+
def main():
86+
print("\n🔍 Collecting Git repository statistics...\n")
87+
88+
stats = get_git_stats()
89+
90+
if "error" in stats:
91+
print(f"❌ Error: {stats['error']}")
92+
print("Make sure you're in a git repository!")
93+
return
94+
95+
display_stats(stats)
96+
save_activity_log(stats)
97+
98+
print("\n📊 For GitHub-specific metrics (clones, views, forks):")
99+
print(" Visit: https://github.com/Lackadaisical-Security/Voynich-Script-Decoded/graphs/traffic")
100+
print("\n")
101+
102+
if __name__ == "__main__":
103+
main()

0 commit comments

Comments
 (0)