Spaces:
Sleeping
Sleeping
File size: 9,546 Bytes
3045238 99b3ef5 3045238 a676448 3045238 e4ee4df 3045238 75d4ca3 3045238 287228a e8bbf2e 420ea26 e8bbf2e 420ea26 57bd653 3045238 75d4ca3 7a778e3 75d4ca3 e8bbf2e 75d4ca3 7a778e3 57bd653 7a778e3 57bd653 084e807 75d4ca3 e8bbf2e 084e807 75d4ca3 57bd653 084e807 8992d21 4428eed 8992d21 75d4ca3 084e807 401d60b 420ea26 e4ee4df 4428eed 084e807 4428eed 420ea26 084e807 7a778e3 420ea26 e4ee4df 420ea26 57bd653 084e807 4428eed 57bd653 e4ee4df 57bd653 4428eed 57bd653 3045238 084e807 4428eed 420ea26 3045238 4428eed 084e807 e4ee4df 4428eed e4ee4df 084e807 4428eed 084e807 4428eed 084e807 4428eed 084e807 e4ee4df 084e807 287228a 084e807 287228a 084e807 287228a 084e807 287228a 4ef0b13 e8bbf2e 3045238 e4ee4df e8bbf2e 4428eed 084e807 287228a e4ee4df e8bbf2e 287228a 4ef0b13 57bd653 3045238 287228a 084e807 420ea26 084e807 1b969ef 3045238 287228a 4ef0b13 287228a 4ef0b13 287228a 084e807 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 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
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
import os
import tempfile
# --- 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):
"""Formats day-month-year into English words with ordinal day."""
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")
# Tag auslesen und in Ordinalform umwandeln
day = date_obj.day
day_ordinal = number_to_ordinal_word(day)
return f"{day_ordinal} {month} {year_formatted}"
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 each day in 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:
# 1) 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})
# 2) Month+Year calculation (only once per unique month-year)
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
})
# 3) Year-only calculation (only once per unique 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 generate_json_output(results, start_date, end_date, include_words, min_results):
"""
Erzeugt ein Dictionary (später für gr.JSON) mit Filterung nach Mindestanzahl,
wenn min_results nicht None ist.
"""
output = {
"DateRange": {
"StartDate": start_date.strftime("%Y-%m-%d"),
"EndDate": end_date.strftime("%Y-%m-%d")
},
"Results": []
}
for gematria_sum, entries in results.items():
# Falls eine Mindestanzahl gefordert ist, filtern
if min_results is not None and len(entries) < min_results:
continue
group = {
"GematriaSum": gematria_sum,
"Entries": []
}
for entry in entries:
entry_data = {"date": entry["date"]}
if include_words:
entry_data["date_words"] = entry["date_words"]
group["Entries"].append(entry_data)
output["Results"].append(group)
return output # <-- Wichtig: Als Dictionary zurückgeben
def perform_calculation(start_date, end_date, include_words, min_results):
"""
Führt die Gematria-Berechnung durch und gibt ein Dictionary zurück,
das direkt an gr.JSON übergeben werden kann.
"""
results = perform_gematria_calculation_for_date_range(start_date, end_date)
return generate_json_output(results, start_date, end_date, include_words, min_results)
def download_json(json_data, start_date, end_date):
"""
Nimmt das JSON-Dict (aus gr.JSON) und legt es als Datei ab,
deren Pfad wir zurückgeben.
Ältere Gradio-Versionen erwarten hier typischerweise einen String
(also File-Pfad), keinen Tuple oder dict.
"""
# Einen Dateinamen konstruieren – der taucht nur intern auf:
filename = f"gematria_{start_date.strftime('%Y%m%d')}_{end_date.strftime('%Y%m%d')}.json"
# Dictionary -> JSON-String
json_string = json.dumps(json_data, indent=4, ensure_ascii=False)
# Temporäre Datei erstellen
# delete=False => Datei bleibt bestehen, bis wir sie manuell entfernen wollen
temp = tempfile.NamedTemporaryFile(suffix=".json", delete=False)
temp_path = temp.name # Pfad merken
try:
# Schreiben als Bytes
temp.write(json_string.encode("utf-8"))
temp.flush()
finally:
# Datei-Handle schließen
temp.close()
# Jetzt returnen wir den Pfad
# => Gradio wird damit umgehen können und bietet Download an
return temp_path
# --- 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")
with gr.Row():
include_date_words = gr.Checkbox(value=True, label="Include Date-Words in JSON")
filter_results = gr.Checkbox(value=False, label="Filter to sums with at least")
min_results_input = gr.Number(value=2, label="results", interactive=True, precision=0)
calculate_btn = gr.Button("Calculate Gematria for Date Range")
json_output = gr.JSON(label="JSON Output")
download_btn = gr.Button("Download JSON")
json_file = gr.File(label="Downloaded JSON")
# Damit wir den Wert von filter_results berücksichtigen können:
def handle_calculate(start_val, end_val, include_val, filter_val, min_val):
if not filter_val: # Checkbox nicht gesetzt
# => Kein Filtern, also min_results=None
return perform_calculation(start_val, end_val, include_val, None)
else:
# => Filter aktiviert, also min_results = min_val
# min_val kann float sein; auf int casten, falls gewünscht
return perform_calculation(start_val, end_val, include_val, int(min_val))
# Button-Klick: wir rufen handle_calculate auf,
# das ggf. min_results auf None setzt oder den Wert übernimmt.
calculate_btn.click(
handle_calculate,
inputs=[start_date, end_date, include_date_words, filter_results, min_results_input],
outputs=[json_output],
api_name="calculate_gematria"
)
# Hier der "fix" im Download-Button
download_btn.click(
download_json, # unsere neue Funktion
inputs=[json_output, start_date, end_date],
outputs=[json_file] # gr.File-Element
)
filter_results.change(
lambda checked: gr.update(interactive=checked),
inputs=filter_results,
outputs=min_results_input
)
if __name__ == "__main__":
app.launch(share=False)
|