File size: 7,278 Bytes
3045238
 
99b3ef5
3045238
 
a676448
3045238
e4ee4df
3045238
75d4ca3
3045238
e8bbf2e
420ea26
e8bbf2e
420ea26
 
 
57bd653
3045238
75d4ca3
 
 
 
 
 
 
 
 
 
 
 
7a778e3
75d4ca3
e8bbf2e
75d4ca3
7a778e3
57bd653
 
 
 
 
 
 
 
7a778e3
57bd653
75d4ca3
e8bbf2e
75d4ca3
 
 
 
 
 
 
 
57bd653
 
 
 
 
 
 
 
8992d21
4428eed
 
 
 
 
 
 
 
 
 
8992d21
75d4ca3
e8bbf2e
401d60b
420ea26
 
 
e4ee4df
4428eed
 
 
420ea26
4428eed
7a778e3
 
420ea26
e4ee4df
420ea26
 
57bd653
 
4428eed
 
 
 
 
57bd653
e4ee4df
57bd653
 
 
4428eed
57bd653
 
3045238
4428eed
 
 
 
 
 
 
 
 
 
 
 
 
 
420ea26
3045238
 
 
57bd653
4428eed
 
 
 
 
 
 
57bd653
 
4428eed
e8bbf2e
e4ee4df
 
 
 
 
4428eed
e4ee4df
4428eed
 
 
 
 
 
 
 
 
 
 
 
 
e4ee4df
 
4ef0b13
e8bbf2e
3045238
e4ee4df
e8bbf2e
 
4428eed
57bd653
e4ee4df
e8bbf2e
 
4ef0b13
57bd653
3045238
e8bbf2e
420ea26
 
57bd653
1b969ef
 
3045238
 
4ef0b13
57bd653
4ef0b13
 
 
 
3045238
4428eed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)

import gradio as gr
from gradio_calendar import Calendar
from gematria import calculate_gematria, strip_diacritics
from datetime import datetime, timedelta
import json
import inflect

# --- Helper Functions ---
def calculate_gematria_sum(text):
    """Calculates the gematria sum of a given text."""
    if text:
        text_gematria = calculate_gematria(strip_diacritics(text))
        return text_gematria
    return None

def number_to_ordinal_word(number):
    ordinal_dict = {
        1: "first", 2: "second", 3: "third", 4: "fourth", 5: "fifth",
        6: "sixth", 7: "seventh", 8: "eighth", 9: "ninth", 10: "tenth",
        11: "eleventh", 12: "twelfth", 13: "thirteenth", 14: "fourteenth",
        15: "fifteenth", 16: "sixteenth", 17: "seventeenth", 18: "eighteenth",
        19: "nineteenth", 20: "twentieth", 21: "twentyfirst", 22: "twentysecond",
        23: "twentythird", 24: "twentyfourth", 25: "twentyfifth",
        26: "twentysixth", 27: "twentyseventh", 28: "twentyeighth",
        29: "twentyninth", 30: "thirtieth", 31: "thirtyfirst"
    }
    return ordinal_dict.get(number, "")

def date_to_words(date_string):
    """Converts a date in YYYY-MM-DD format to English words."""
    inf_engine = inflect.engine()
    date_obj = datetime.strptime(date_string, "%Y-%m-%d")
    return format_date(date_obj, inf_engine)


def month_year_to_words(date_string):
    """Converts a month and year in YYYY-MM format to English words."""
    inf_engine = inflect.engine()
    date_obj = datetime.strptime(date_string, "%Y-%m")
    return format_date(date_obj, inf_engine)

def format_date(date_obj, inf_engine):
    year = date_obj.year
    if 1100 <= year <= 1999:
        year_words = f"{inf_engine.number_to_words(year // 100, andword='') } hundred"
        if year % 100 != 0:
            year_words += f" {inf_engine.number_to_words(year % 100, andword='')}"
    else:
        year_words = inf_engine.number_to_words(year, andword='')
    year_formatted = year_words.replace(',', '')

    month = date_obj.strftime("%B")
    
    try:  # Try getting the day, if available
        day = date_obj.day
        day_ordinal = number_to_ordinal_word(day)
        return f"{day_ordinal} {month} {year_formatted}" # Return with day
    except: 
        return f"{month} {year_formatted}"  # Return without day


def format_year_to_words(year):
    """Formats a year as English words."""
    inf_engine = inflect.engine()
    if 1100 <= year <= 1999:
        year_words = f"{inf_engine.number_to_words(year // 100, andword='')} hundred"
        if year % 100 != 0:
            year_words += f" {inf_engine.number_to_words(year % 100, andword='')}"
    else:
        year_words = inf_engine.number_to_words(year, andword='')
    return year_words.replace(',', '')

def perform_gematria_calculation_for_date_range(start_date, end_date):
    """Performs gematria calculation for a date range and groups by sum."""
    logger.debug(f"Start Date: {start_date}, End Date: {end_date}")
    results = {}
    delta = timedelta(days=1)
    current_date = start_date

    processed_months = set()  # To track processed month-year combinations
    processed_years = set()  # To track processed years

    while current_date <= end_date:
        # Full date calculation
        date_string = current_date.strftime("%Y-%m-%d")
        date_words = date_to_words(date_string)
        gematria_sum = calculate_gematria_sum(date_words)

        if gematria_sum not in results:
            results[gematria_sum] = []
        results[gematria_sum].append({"date": date_string, "date_words": date_words})

        # Month+Year calculation (processed once per month)
        month_year_key = current_date.strftime("%Y-%m")
        if month_year_key not in processed_months:
            processed_months.add(month_year_key)
            month_year_words = f"{current_date.strftime('%B')} {format_year_to_words(current_date.year)}"
            month_year_gematria_sum = calculate_gematria_sum(month_year_words)

            if month_year_gematria_sum not in results:
                results[month_year_gematria_sum] = []
            results[month_year_gematria_sum].append({
                "date": month_year_key,
                "date_words": month_year_words
            })

        # Year-only calculation (processed once per year)
        year_key = str(current_date.year)
        if year_key not in processed_years:
            processed_years.add(year_key)
            year_words = format_year_to_words(current_date.year)
            year_gematria_sum = calculate_gematria_sum(year_words)

            if year_gematria_sum not in results:
                results[year_gematria_sum] = []
            results[year_gematria_sum].append({
                "date": year_key,
                "date_words": year_words
            })

        current_date += delta

    return results


# --- Event Handlers ---
def perform_calculation(start_date, end_date, include_words):
    """Performs the calculation and generates the JSON output."""
    logger.debug(f"perform_calculation called with: start_date={start_date}, end_date={end_date}, include_words={include_words}")
    results = perform_gematria_calculation_for_date_range(start_date, end_date)
    json_result = generate_json_output(results, start_date, end_date, include_words)
    return json_result


def generate_json_output(results, start_date, end_date, include_words):
    """Generates the JSON output with the date range and results."""
    result = {
        "DateRange": {
            "StartDate": start_date.strftime("%Y-%m-%d"),
            "EndDate": end_date.strftime("%Y-%m-%d")
        },
        "Results": []
    }
    for gematria_sum, entries in results.items():
        group = {
            "GematriaSum": gematria_sum,
            "Entries": []
        }
        for entry in entries:
            entry_data = {"date": entry["date"]}
            if include_words:  # Conditionally include `date_words`
                entry_data["date_words"] = entry["date_words"]
            group["Entries"].append(entry_data)
        result["Results"].append(group)

    # Ensure JSON validity
    return json.dumps(result, indent=4, ensure_ascii=False)


# --- Main Gradio App ---
with gr.Blocks() as app:
    with gr.Row():
        start_date = Calendar(type="datetime", label="Start Date")
        end_date = Calendar(type="datetime", label="End Date")

    include_date_words = gr.Checkbox(value=True, label="Include Date-Words in JSON")

    calculate_btn = gr.Button("Calculate Gematria for Date Range")
    json_output = gr.Textbox(label="JSON Output")
    download_btn = gr.Button("Download JSON")
    json_file = gr.File(label="Downloaded JSON")

    # --- Event Triggers ---
    calculate_btn.click(
        perform_calculation,
        inputs=[start_date, end_date, include_date_words],
        outputs=[json_output],
        api_name="calculate_gematria"
    )

    download_btn.click(
        lambda json_data, start_date, end_date: download_json(json_data, start_date, end_date),
        inputs=[json_output, start_date, end_date],
        outputs=[json_file],
    )

if __name__ == "__main__":
    app.launch(share=False)