Spaces:
Sleeping
Sleeping
import logging | |
logger = logging.getLogger(__name__) | |
import os | |
import re | |
from deep_translator import GoogleTranslator | |
from deep_translator import exceptions | |
from gematria import calculate_gematria | |
import math | |
import xml.etree.ElementTree as ET | |
import glob | |
# Hebrew letters and whitespace range | |
DIACRITICS_REGEX = re.compile(r"[^\u05D0-\u05EA\s]+") | |
def process_json_files(start, end, step, rounds="1", length=0, | |
tlang="en", | |
strip_spaces=True, | |
strip_in_braces=True, | |
strip_diacritics=True, | |
translate=False): | |
base_path = "texts/tanach" | |
translator = GoogleTranslator(source='auto', target=tlang) | |
results = [] | |
for i in range(start, end + 1): | |
file_pattern = f"{base_path}/{i:02}*.xml" | |
matching_files = glob.glob(file_pattern) | |
if not matching_files: | |
results.append({"error": f"No file matching pattern '{file_pattern}' found."}) | |
continue | |
for file_name in matching_files: | |
try: | |
tree = ET.parse(file_name) | |
root = tree.getroot() | |
# Step 1: Collect text by verse, each verse's words joined by spaces | |
text_blocks = [] | |
for verse in root.findall('.//v'): | |
verse_words = [] | |
for word in verse.findall('./w'): | |
verse_words.append("".join(word.itertext())) | |
# Now join words into a single verse string | |
verse_text = " ".join(verse_words) | |
text_blocks.append(verse_text) | |
# Step 2: Join all verses with spaces to get a single string | |
full_text = " ".join(text_blocks) | |
# -- The rest of the cleaning logic remains as before -- | |
if strip_in_braces: | |
full_text = re.sub(r"\[.*?\]", "", full_text, flags=re.DOTALL) | |
if strip_diacritics: | |
full_text = DIACRITICS_REGEX.sub("", full_text) | |
if strip_spaces: | |
# Remove *all* spaces | |
full_text = full_text.replace(" ", "") | |
else: | |
# Collapse multiple spaces into one | |
full_text = re.sub(r'\s+', ' ', full_text) | |
text_length = len(full_text) | |
if text_length == 0: | |
# If after cleaning, there's no text, skip | |
continue | |
rounds_list = list(map(float, rounds.split(','))) # Allow floats | |
result_text = "" | |
# -- Rounds logic (unchanged) -- | |
for r in rounds_list: | |
abs_r = abs(r) | |
full_passes = math.floor(abs_r) | |
remainder = abs_r - full_passes | |
base_chars = text_length // step | |
if base_chars == 0: | |
if abs_r > 1: | |
chars_per_full_pass = 1 | |
else: | |
chars_per_full_pass = 0 | |
chars_for_remainder = 0 | |
else: | |
chars_per_full_pass = base_chars | |
chars_for_remainder = math.floor(base_chars * remainder) | |
if r > 0: | |
current_index = (step - 1) % text_length | |
direction = 1 | |
else: | |
current_index = (text_length - step) % text_length | |
direction = -1 | |
pass_result = "" | |
for pass_num in range(1, full_passes + 1): | |
current_pass_chars = "" | |
for _ in range(chars_per_full_pass): | |
if chars_per_full_pass == 0: | |
break | |
current_pass_chars += full_text[current_index] | |
current_index = (current_index + direction * step) % text_length | |
# Keep only the last full pass | |
if pass_num == full_passes: | |
pass_result = current_pass_chars | |
if remainder > 0 and chars_for_remainder > 0: | |
current_pass_chars = "" | |
for _ in range(chars_for_remainder): | |
current_pass_chars += full_text[current_index] | |
current_index = (current_index + direction * step) % text_length | |
pass_result += current_pass_chars | |
result_text += pass_result | |
# Optional translation | |
translated_text = "" | |
if translate and result_text: | |
translated_text = translator.translate(result_text) | |
if length != 0: | |
result_text = result_text[:length] | |
# Append final if we have any picked text | |
if result_text: | |
title_el = root.find('.//names/name') | |
title_str = title_el.text if title_el is not None else os.path.basename(file_name) | |
results.append({ | |
"book": i, | |
"title": title_str, | |
"result_text": result_text, | |
"result_sum": calculate_gematria(result_text), | |
"translated_text": translated_text, | |
"source_language": "he", | |
}) | |
except FileNotFoundError: | |
results.append({"error": f"File {file_name} not found."}) | |
except ET.ParseError as e: | |
results.append({"error": f"File {file_name} could not be read as XML: {e}"}) | |
except KeyError as e: | |
results.append({"error": f"Expected key 'text' is missing in {file_name}: {e}"}) | |
logger.debug(f"Returning results from torah.process_json_files: {results}") | |
return results | |
# Tests | |
test_results = [ | |
(process_json_files(0, 0, 21, rounds="3", length=0), "ק"), | |
(process_json_files(0, 0, 22, rounds="1", length=0), "ת"), | |
(process_json_files(0, 0, 22, rounds="3", length=0), "ת"), | |
(process_json_files(0, 0, 23, rounds="3", length=0), "ג"), | |
(process_json_files(0, 0, 11, rounds="1", length=0), "כת"), | |
(process_json_files(0, 0, 2, rounds="1", length=0), "בדוחילנעצרת"), | |
(process_json_files(0, 0, 23, rounds="1", length=0), None), # Expect None, when no results | |
(process_json_files(0, 0, 23, rounds="-1", length=0), None), # Expect None, when no results | |
(process_json_files(0, 0, 22, rounds="-1", length=0), "א"), | |
(process_json_files(0, 0, 22, rounds="-2", length=0), "א"), | |
(process_json_files(0, 0, 1, rounds="1,-1", length=0), "אבגדהוזחטיכלמנסעפצקרשתתשרקצפעסנמלכיטחזוהדגבא"), # Combined rounds | |
(process_json_files(0, 0, 1, rounds="-1", length=0), "תשרקצפעסנמלכיטחזוהדגבא"), # Reversed Hebrew alphabet | |
(process_json_files(0, 0, 1, rounds="-1.5", length=0), "תשרקצפעסנמלכיטחזוהדגבאתשרקצפעסנמל"), # Fractional rounds | |
] | |
all_tests_passed = True | |
for result, expected in test_results: | |
result_text = result[0]['result_text'] if result else None | |
if expected is None: # Check if no result is expected | |
if not result: | |
logger.warning(f"Test passed: Expected no results, got no results.") | |
else: | |
logger.error(f"Test failed: Expected no results, but got: {result_text}") | |
all_tests_passed = False | |
else: | |
# Check if result is not empty before accessing elements | |
if result: | |
if result_text == expected: | |
logger.warning(f"Test passed: Expected '{expected}', got '{result_text}'") | |
else: | |
logger.error(f"Test failed: Expected '{expected}', but got '{result_text}'") | |
all_tests_passed = False | |
else: | |
logger.error(f"Test failed: Expected '{expected}', but got no results") | |
all_tests_passed = False | |
if all_tests_passed: | |
logger.info("All round tests passed.") | |