diff --git a/kjvstudy_org/server.py b/kjvstudy_org/server.py index 46362de..5e6216d 100644 --- a/kjvstudy_org/server.py +++ b/kjvstudy_org/server.py @@ -1268,6 +1268,158 @@ def get_daily_verse(date_str=None): +@app.get("/stats", response_class=HTMLResponse) +async def stats(request: Request): + """Hidden statistics page - comprehensive site metrics""" + import json + from pathlib import Path + + data_dir = Path(__file__).parent / "data" + + # Bible statistics + total_verses = bible.get_verse_count() + total_books = len(bible.get_books()) + total_chapters = len(bible.get_chapters()) + + # Calculate words in Bible + total_words = sum(len(verse.text.split()) for verse in bible.iter_verses()) + + # Count unique book types + ot_books = len(OT_BOOKS) + nt_books = len(NT_BOOKS) + + # Data file statistics + total_json_files = len(list(data_dir.glob('**/*.json'))) + + # Verse commentary statistics + verse_commentary_files = len(list((data_dir / 'verse_commentary').glob('*.json'))) + total_commentary_verses = 0 + total_commentary_words = 0 + for file in (data_dir / 'verse_commentary').glob('*.json'): + data = json.load(open(file)) + commentary = data.get('commentary', {}) + for chapter in commentary.values(): + for verse_data in chapter.values(): + total_commentary_verses += 1 + # Count words in analysis + historical + analysis = verse_data.get('analysis', '') + historical = verse_data.get('historical', '') + # Strip HTML tags for accurate word count + import re + clean_analysis = re.sub(r'<[^>]+>', '', analysis) + clean_historical = re.sub(r'<[^>]+>', '', historical) + total_commentary_words += len(clean_analysis.split()) + len(clean_historical.split()) + + # Cross-reference statistics + cross_reference_files = len(list((data_dir / 'cross_references').glob('*.json'))) + total_cross_refs = 0 + verses_with_cross_refs = 0 + for file in (data_dir / 'cross_references').glob('*.json'): + data = json.load(open(file)) + verses_with_cross_refs += len(data) + for verse_refs in data.values(): + total_cross_refs += len(verse_refs) + + # Red letter statistics + red_letter_data = json.load(open(data_dir / 'red_letter_verses.json')) + total_red_letter_verses = len(red_letter_data['verses']) + + # Study resources + study_guide_files = len(list((data_dir / 'study_guides').glob('*.json'))) + topic_files = len(list((data_dir / 'topics').glob('*.json'))) + resource_files = len(list((data_dir / 'resources').glob('*.json'))) + story_files = len(list((data_dir / 'stories').glob('*.json'))) + + # Interlinear data size + interlinear_file = data_dir / 'interlinear.json.gz' + interlinear_size_mb = interlinear_file.stat().st_size / 1024 / 1024 if interlinear_file.exists() else 0 + + # Calculate total data directory size + total_data_size = sum(f.stat().st_size for f in data_dir.glob('**/*') if f.is_file()) + total_data_size_mb = total_data_size / 1024 / 1024 + + # Book abbreviations + bible_metadata_file = data_dir / 'bible_metadata.json' + bible_metadata = json.load(open(bible_metadata_file)) + total_abbreviations = len(bible_metadata.get('book_abbreviations', {})) + + # Biographies + bio_data = json.load(open(data_dir / 'biographies.json')) + total_biographies = len(bio_data.get('biographies', {})) + + # Reading plans + reading_plan_files = len(list((data_dir / 'reading_plans').glob('*.json'))) + + # Strong's concordance + strongs_dir = data_dir / 'strongs' + if strongs_dir.exists(): + hebrew_data = json.load(open(strongs_dir / 'hebrew.json')) + greek_data = json.load(open(strongs_dir / 'greek.json')) + total_hebrew_entries = len(hebrew_data) + total_greek_entries = len(greek_data) + else: + total_hebrew_entries = 0 + total_greek_entries = 0 + + stats_data = { + 'bible': { + 'total_verses': total_verses, + 'total_books': total_books, + 'ot_books': ot_books, + 'nt_books': nt_books, + 'total_chapters': total_chapters, + 'total_words': total_words, + 'avg_words_per_verse': round(total_words / total_verses, 1), + 'avg_verses_per_chapter': round(total_verses / total_chapters, 1), + }, + 'commentary': { + 'files': verse_commentary_files, + 'verses_covered': total_commentary_verses, + 'total_words': total_commentary_words, + 'avg_words_per_verse': round(total_commentary_words / total_commentary_verses, 1) if total_commentary_verses > 0 else 0, + 'coverage_percent': round((total_commentary_verses / total_verses) * 100, 1), + }, + 'cross_references': { + 'files': cross_reference_files, + 'verses_with_refs': verses_with_cross_refs, + 'total_references': total_cross_refs, + 'avg_refs_per_verse': round(total_cross_refs / verses_with_cross_refs, 1) if verses_with_cross_refs > 0 else 0, + 'coverage_percent': round((verses_with_cross_refs / total_verses) * 100, 1), + }, + 'red_letter': { + 'total_verses': total_red_letter_verses, + 'percent_of_bible': round((total_red_letter_verses / total_verses) * 100, 1), + }, + 'study_resources': { + 'study_guides': study_guide_files, + 'topics': topic_files, + 'resources': resource_files, + 'stories': story_files, + 'biographies': total_biographies, + 'reading_plans': reading_plan_files, + }, + 'language_tools': { + 'hebrew_entries': total_hebrew_entries, + 'greek_entries': total_greek_entries, + 'total_strongs': total_hebrew_entries + total_greek_entries, + 'interlinear_size_mb': round(interlinear_size_mb, 1), + }, + 'data': { + 'total_json_files': total_json_files, + 'total_size_mb': round(total_data_size_mb, 1), + 'book_abbreviations': total_abbreviations, + } + } + + return templates.TemplateResponse( + "stats.html", + { + "request": request, + "stats": stats_data, + } + ) + + @app.get("/", response_class=HTMLResponse) async def read_root(request: Request): books = bible.get_books() diff --git a/kjvstudy_org/templates/stats.html b/kjvstudy_org/templates/stats.html new file mode 100644 index 0000000..489d418 --- /dev/null +++ b/kjvstudy_org/templates/stats.html @@ -0,0 +1,252 @@ +{% extends "base.html" %} + +{% block title %}Site Statistics - KJV Study{% endblock %} +{% block description %}Comprehensive statistics about KJV Study - Bible data, commentary, cross-references, and study resources{% endblock %} + +{% block content %} +
+

KJV Study Statistics

+

Comprehensive metrics about this Bible study resource

+ +
+

Bible Text

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Total Verses{{ "{:,}".format(stats.bible.total_verses) }}
Total Books{{ stats.bible.total_books }} ({{ stats.bible.ot_books }} OT + {{ stats.bible.nt_books }} NT)
Total Chapters{{ "{:,}".format(stats.bible.total_chapters) }}
Total Words{{ "{:,}".format(stats.bible.total_words) }}
Average Words per Verse{{ stats.bible.avg_words_per_verse }}
Average Verses per Chapter{{ stats.bible.avg_verses_per_chapter }}
+
+ +
+

Verse Commentary

+

In-depth theological analysis with Greek/Hebrew word studies

+ + + + + + + + + + + + + + + + + + + + + +
Commentary Files{{ stats.commentary.files }} books
Verses with Commentary{{ "{:,}".format(stats.commentary.verses_covered) }}
Coverage{{ stats.commentary.coverage_percent }}% of Bible
Total Commentary Words{{ "{:,}".format(stats.commentary.total_words) }}
Average Words per Verse{{ "{:,}".format(stats.commentary.avg_words_per_verse|int) }}
+
+ +
+

Cross-References

+

Based on Treasury of Scripture Knowledge (CC-BY)

+ + + + + + + + + + + + + + + + + + + + + +
Files{{ stats.cross_references.files }} books
Verses with Cross-References{{ "{:,}".format(stats.cross_references.verses_with_refs) }}
Coverage{{ stats.cross_references.coverage_percent }}% of Bible
Total Cross-References{{ "{:,}".format(stats.cross_references.total_references) }}
Average per Verse{{ stats.cross_references.avg_refs_per_verse }}
+
+ +
+

Red Letter Edition

+

Words of Jesus Christ

+ + + + + + + + + +
Verses{{ "{:,}".format(stats.red_letter.total_verses) }}
Percentage of Bible{{ stats.red_letter.percent_of_bible }}%
+
+ +
+

Language Tools

+

Hebrew, Greek, and interlinear resources

+ + + + + + + + + + + + + + + + + +
Hebrew Strong's Entries{{ "{:,}".format(stats.language_tools.hebrew_entries) }}
Greek Strong's Entries{{ "{:,}".format(stats.language_tools.greek_entries) }}
Total Strong's Concordance{{ "{:,}".format(stats.language_tools.total_strongs) }}
Interlinear Data Size{{ stats.language_tools.interlinear_size_mb }} MB (compressed)
+
+ +
+

Study Resources

+

Topical studies, reading plans, and biblical resources

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Study Guides{{ stats.study_resources.study_guides }}
Topics{{ stats.study_resources.topics }}
Resources{{ stats.study_resources.resources }}
Bible Stories{{ stats.study_resources.stories }}
Biographies{{ stats.study_resources.biographies }} biblical figures
Reading Plans{{ stats.study_resources.reading_plans }}
+
+ +
+

Technical Data

+

Data files and infrastructure

+ + + + + + + + + + + + + +
Total JSON Files{{ "{:,}".format(stats.data.total_json_files) }}
Total Data Size{{ stats.data.total_size_mb }} MB
Book Abbreviations{{ stats.data.book_abbreviations }}
+
+ +
+

Summary

+

KJV Study contains:

+ +
+ +

+ This is a hidden page not linked from navigation. Access via direct URL: /stats +

+
+ + +{% endblock %}