Last active
April 8, 2018 19:05
-
-
Save dmattera/2c480e41c85802fb9af07aa7a7d3d4ca to your computer and use it in GitHub Desktop.
Pythonista translator extension
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import appex, console, clipboard | |
import html, requests | |
from urllib.parse import quote_plus, urlencode | |
# translate from the share menu in most apps # (e.g. WhatsApp - like so: https://imgur.com/a/6D5fi) or from the clipboard | |
# translations come from Google Translate API and require a free API key. https://cloud.google.com/translate/docs/quickstart | |
# Current working environment | |
# iOS 11.3 | |
# WhatsApp 2.18.40 | |
# Pythonista 3.2 | |
TARGET_LANG = "en" # uses ISO-639-1 codes: https://cloud.google.com/translate/docs/languages | |
SOURCE_LANG = "auto" # uses ISO codes or 'auto' to utilize Google's auto-detect ability | |
API_KEY = 'YOUR_API_KEY' | |
def main(): | |
if appex.is_running_extension(): | |
text = get_appex_text() # returns a list of dictionaries or None if no text is present | |
else: | |
text = [{'orig_text': clipboard.get()}] | |
if text: | |
if SOURCE_LANG == "auto": | |
detected_text = detect(text) | |
translated_text = translate(text=detected_text) | |
else: | |
translated_text = translate(text=text) | |
display_text(translated_text) | |
else: | |
console.alert('Error', 'No text selected.','OK', hide_cancel_button=True) | |
def get_appex_text(): | |
appex_text = appex.get_text() | |
if appex_text: | |
if '\n' in appex_text: | |
seperate_texts = appex_text.split('\n') | |
text = [] | |
for t in seperate_texts: | |
if t != '': | |
text.append({'orig_text': t}) | |
else: | |
text = [{'orig_text': appex_text}] | |
return text | |
else: | |
return None | |
def api_url(text, method): | |
url = "https://www.googleapis.com/language/translate/v2" | |
if method == "detect": | |
url += "/detect?key=" + API_KEY | |
for t in text: | |
payload = {'q': t['orig_text']} | |
encoded_payload = urlencode(payload, quote_via=quote_plus) | |
url += "&" + encoded_payload | |
elif method == "translate": | |
url += "?key=" + API_KEY | |
for t in text: | |
if SOURCE_LANG == "auto": | |
payload = {'q': t['orig_text'], 'source': t['language'], 'target': TARGET_LANG} | |
else: | |
payload = {'q': t['orig_text'], 'source': SOURCE_LANG, 'target': TARGET_LANG} | |
encoded_payload = urlencode(payload, quote_via=quote_plus) | |
url += '&' + encoded_payload | |
return url | |
def detect(text): | |
r = requests.get(url=api_url(text, method="detect")) | |
detections = r.json()['data']['detections'] | |
detected_messages = [] | |
for n, det in enumerate(detections): | |
temp = {} | |
temp['language'] = det[0]['language'] | |
temp['confidence'] = det[0]['confidence'] | |
temp['orig_text'] = text[n]['orig_text'] | |
detected_messages.append(temp) | |
return detected_messages | |
def translate(text): | |
r = requests.get(url=api_url(text=text, method="translate")) | |
translations = r.json()['data']['translations'] | |
translated_text = [] | |
for n, t in enumerate(text): | |
temp = {} | |
temp['orig_text'] = t['orig_text'] | |
temp['language'] = t['language'] | |
temp['confidence'] = t['confidence'] | |
temp['trans_text'] = html.unescape(s=translations[n]['translatedText']) | |
translated_text.append(temp) | |
return translated_text | |
def display_text(translated_text): | |
output = '' | |
for text in translated_text: | |
if SOURCE_LANG == "auto": | |
source_long_name = lookup_language(text['language']) | |
else: | |
source_long_name = lookup_language(SOURCE_LANG) | |
target_long_name = lookup_language(TARGET_LANG) | |
output += '[{}] {}\n[{}] {}\n\n'.format(source_long_name, text['orig_text'], target_long_name, text['trans_text']) | |
if len(translated_text) > 1: | |
title = "Translation" | |
else: | |
title = "Translations" | |
console.alert(title, str(output), 'OK', hide_cancel_button=True) | |
def lookup_language(code): | |
# returns full language name based on the given ISO-639-1 code | |
language = "" | |
lang_codes = { | |
'af': 'Afrikaans', | |
'sq': 'Albanian', | |
'am': 'Amharic', | |
'ar': 'Arabic', | |
'hy': 'Armenian', | |
'az': 'Azeerbaijani', | |
'eu': 'Basque', | |
'be': 'Belarusian', | |
'bn': 'Bengali', | |
'bs': 'Bosnian', | |
'bg': 'Bulgarian', | |
'ca': 'Catalan', | |
'ceb (ISO-639-2)': 'Cebuano', | |
'zh-CN (BCP-47)': 'Chinese (Simplified)', | |
'zh-TW (BCP-47)': 'Chinese (Traditional)', | |
'co': 'Corsican', | |
'hr': 'Croatian', | |
'cs': 'Czech', | |
'da': 'Danish', | |
'nl': 'Dutch', | |
'en': 'English', | |
'eo': 'Esperanto', | |
'et': 'Estonian', | |
'fi': 'Finnish', | |
'fr': 'French', | |
'fy': 'Frisian', | |
'gl': 'Galician', | |
'ka': 'Georgian', | |
'de': 'German', | |
'el': 'Greek', | |
'gu': 'Gujarati', | |
'ht': 'Haitian Creole', | |
'ha': 'Hausa', | |
'haw (ISO-639-2)': 'Hawaiian', | |
'iw': 'Hebrew', | |
'hi': 'Hindi', | |
'hmn (ISO-639-2)': 'Hmong', | |
'hu': 'Hungarian', | |
'is': 'Icelandic', | |
'ig': 'Igbo', | |
'id': 'Indonesian', | |
'ga': 'Irish', | |
'it': 'Italian', | |
'ja': 'Japanese', | |
'jw': 'Javanese', | |
'kn': 'Kannada', | |
'kk': 'Kazakh', | |
'km': 'Khmer', | |
'ko': 'Korean', | |
'ku': 'Kurdish', | |
'ky': 'Kyrgyz', | |
'lo': 'Lao', | |
'la': 'Latin', | |
'lv': 'Latvian', | |
'lt': 'Lithuanian', | |
'lb': 'Luxembourgish', | |
'mk': 'Macedonian', | |
'mg': 'Malagasy', | |
'ms': 'Malay', | |
'ml': 'Malayalam', | |
'mt': 'Maltese', | |
'mi': 'Maori', | |
'mr': 'Marathi', | |
'mn': 'Mongolian', | |
'my': 'Myanmar (Burmese)', | |
'ne': 'Nepali', | |
'no': 'Norwegian', | |
'ny': 'Nyanja (Chichewa)', | |
'ps': 'Pashto', | |
'fa': 'Persian', | |
'pl': 'Polish', | |
'pt': 'Portuguese (Portugal, Brazil)', | |
'pa': 'Punjabi', | |
'ro': 'Romanian', | |
'ru': 'Russian', | |
'sm': 'Samoan', | |
'gd': 'Scots Gaelic', | |
'sr': 'Serbian', | |
'st': 'Sesotho', | |
'sn': 'Shona', | |
'sd': 'Sindhi', | |
'si': 'Sinhala (Sinhalese)', | |
'sk': 'Slovak', | |
'sl': 'Slovenian', | |
'so': 'Somali', | |
'es': 'Spanish', | |
'su': 'Sundanese', | |
'sw': 'Swahili', | |
'sv': 'Swedish', | |
'tl': 'Tagalog (Filipino)', | |
'tg': 'Tajik', | |
'ta': 'Tamil', | |
'te': 'Telugu', | |
'th': 'Thai', | |
'tr': 'Turkish', | |
'uk': 'Ukrainian', | |
'ur': 'Urdu', | |
'uz': 'Uzbek', | |
'vi': 'Vietnamese', | |
'cy': 'Welsh', | |
'xh': 'Xhosa', | |
'yi': 'Yiddish', | |
'yo': 'Yoruba', | |
'zu': 'Zulu' | |
} | |
for key, value in lang_codes.items(): | |
if code == key: | |
language = value | |
return language | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment