Files
2025-08-01 22:27:07 +03:00

219 lines
8.4 KiB
Python

from flask import Flask, render_template, request, jsonify
try: from translation_api.translationHelper import TranslationHelper
except ImportError: from .translation_api.translationHelper import TranslationHelper
try: from jsonUtils import Utils
except ImportError: from .jsonUtils import Utils
import os
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
jsonUtils = Utils()
translationHelper = TranslationHelper(deepseekApiToken=os.getenv("DEEPSEEK_API_TOKEN"), yandexApiType="ios")
OLD_TRANSLATION_PROMPT = """You are a master Russian translator specializing in creative adaptations.
For each English phrase, provide exactly 10 Russian translations showing different approaches:
1. Literal translation
2. Idiomatic adaptation (Russian equivalent)
3. Poetic/stylized version
4. Casual/conversational
5. Formal/official
6. Shortened/simplified
7. Expanded/embellished
8. Humorous twist (if appropriate)
9. With little Easter egg based on russian films, games, etc..
10. Creative reimagining
Format strictly as:
1. Translation 1
2. Translation 2
...
10. Translation 10
Never include explanations or additional text.
"""
NEW_TRANSLATION_PROMPT = """You are a master Russian translator specializing in creative adaptations.
For each English phrase, provide exactly 10 Russian translations showing different approaches.
First must contain little Easter egg based on russian films, games, etc.. but others - no.
Format strictly as:
1. Translation 1
2. Translation 2
...
10. Translation 10
Never include explanations or additional text.
"""
LEARNING_TRANSLATION_PROMPT = """You are a master Russian translator specializing in creative adaptations for Minecraft mods. Currently you are translating Oritech mod for Minecraft 1.21.1.
I pasted json with my translations before this message for u to see how translation is already done and what words you should use. If some line in this json contains "//TODO" or "//REDO" or is a whitespace ignore it.
For each English phrase, provide exactly 10 Russian translations showing different approaches.
If you are asked to translate a phrase that is already translated in json i provided, try to make something more simmilar to it and save different accent phrases from it also include one exact same translation as in the json file.
One of translations must be little Easter egg based on russian films, games, etc... Second translation must be in Humorous twist (if appropriate) approach.
Also you must strictly use already translated name for items or blocks if they appear in phrase that i am asking you to translate. Double check conjugation and declension in russian words!
If English phrase is whitespace or empty string ignore it and return one translation: "[Failed] Check text you sent to me.".
Format strictly as:
1. Translation 1
2. Translation 2
...
10. Translation 10
Never include explanations or additional text.
"""
@app.route('/get_translation_suggestions', methods=['POST'])
def get_translation_suggestions():
text = request.json.get('text', '')
if not text:
return jsonify({'error': 'No text provided'}), 400
yandex = translationHelper.getYandexTranslation(text)
google = translationHelper.getGoogleTranslation(text)
deepl = translationHelper.getDeeplTranslation(text)
return jsonify({
'yandex': yandex,
'google': google,
'deepl': deepl,
})
@app.route('/get_ai_suggestions', methods=['POST'])
def get_ai_suggestions():
text = request.json.get('text', '')
if not text:
return jsonify({'error': 'No text provided'}), 400
try:
suggestions = translationHelper.getDeepseekTranslation(text, prompt=NEW_TRANSLATION_PROMPT)
return jsonify({
'suggestions': suggestions
})
except Exception as e:
return jsonify({
'error': str(e),
'suggestions': []
})
@app.route('/get_learning_ai_suggestions', methods=['POST', "GET"])
def get_learning_ai_suggestions():
text = request.json.get('text', '')
if not text:
return jsonify({'error': 'No text provided'}), 400
try:
translations = jsonUtils.get_existing_translations()
new_prompt = str(translations) + "\n" + LEARNING_TRANSLATION_PROMPT
# print(new_prompt)
suggestions = translationHelper.getDeepseekTranslation(text, prompt=new_prompt)
return jsonify({
'suggestions': suggestions
})
except Exception as e:
return jsonify({
'error': str(e),
'suggestions': []
})
@app.route('/')
def show_differences():
ru_file = 'ru_ru.json'
en_file = 'en_us.json'
try:
comparison = jsonUtils.compare_json_files(ru_file, en_file)
# Format for DeepDiff tab (keys are already sorted)
deep_differences = []
if 'values_changed' in comparison['deep_diff']:
for key in sorted(comparison['deep_diff']['values_changed'].keys()):
change = comparison['deep_diff']['values_changed'][key]
deep_differences.append({
'key': key,
'old_value': change['old_value'],
'new_value': change['new_value'],
'type': 'changed'
})
if 'dictionary_item_added' in comparison['deep_diff']:
for key in sorted(comparison['deep_diff']['dictionary_item_added']):
deep_differences.append({
'key': key,
'new_value': comparison['en_data'].get(key.split('root[')[-1][:-1], ''),
'type': 'added'
})
if 'dictionary_item_removed' in comparison['deep_diff']:
for key in sorted(comparison['deep_diff']['dictionary_item_removed']):
deep_differences.append({
'key': key,
'old_value': comparison['ru_data'].get(key.split('root[')[-1][:-1], ''),
'type': 'removed'
})
# Format for KeyCheck tab (keys are already sorted)
key_differences = {
'added': [{'key': k, 'value': comparison['en_data'][k]} for k in comparison['key_diff']['added']],
'removed': [{'key': k, 'value': comparison['ru_data'][k]} for k in comparison['key_diff']['removed']],
'common': comparison['key_diff']['common']
}
# Filter TODO/REDO items
todo_items = []
for item in key_differences['added']:
if isinstance(item['value'], str) and ('//TODO' in item['value'].upper() or '//REDO' in item['value'].upper()):
todo_items.append(item)
# Load existing translations (both original and new, already sorted)
existing_translations = jsonUtils.get_existing_translations()
return render_template('diff.html',
deep_differences=deep_differences,
key_differences=key_differences,
ru_file=ru_file,
en_file=en_file,
existing_translations=existing_translations,
todo_items=todo_items)
except Exception as e:
return render_template('error.html', error=str(e))
@app.route('/save_translations', methods=['POST'])
def save_translations():
translations = request.json
if not translations:
return jsonify({'status': 'error', 'message': 'No translations provided'}), 400
try:
jsonUtils.save_json('newKeys_ru_ru.json', translations)
return jsonify({'status': 'success', 'saved': len(translations)})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
@app.route('/save_todo_translations', methods=['POST'])
def save_todo_translations():
translations = request.json
if not translations:
return jsonify({'status': 'error', 'message': 'No translations provided'}), 400
try:
# Load existing translations
existing_translations = jsonUtils.load_json('newKeys_ru_ru.json')
# Update with new translations
existing_translations.update(translations)
# Save back to file
jsonUtils.save_json('newKeys_ru_ru.json', existing_translations)
return jsonify({'status': 'success', 'saved': len(translations)})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
if __name__ == '__main__':
app.run()