Pythonで作るGUI付き翻訳支援アプリの作成 Part9:アプリの全コードまとめ

Part1 - 8までに作成したファイルのコードをまとめておきます。

main.py

import PySimpleGUI as sg
import configparser
import gui
import deepl


def main():
    # 設定を読み込む。
    config = configparser.ConfigParser()
    config.read('config.ini')
    config_deepl = config['deepL']
    # 最初に表示するウィンドウを指定する。
    window = gui.main_window()
    # deepLの使用量を取得しウィンドウに表示させる。
    gui.get_usage(window, config_deepl)

    while True:
        event, values = window.read()

        if event == '-run_deepl-':
            message = values['-original_text-']

            lng = deepl.lang_set(message)
            # DeepL翻訳実行
            trans_result = deepl.translate(message, t_lang=lng['target'],
                                           s_lang=lng['source'], config=config_deepl)

            # DeepL逆翻訳実行
            lng = deepl.lang_set(trans_result)
            back_trans_result = deepl.translate(trans_result, t_lang=lng['target'],
                                                s_lang=lng['source'], config=config_deepl)
            window['-translated_text-'].print(trans_result)
            window['-back_trans_text-'].print(back_trans_result)

            gui.get_usage(window, config_deepl)

        if event == '-config-':
            window.close()
            window = gui.config_window(config_deepl)

        if event == '-config_update-':
            edit = configparser.ConfigParser()
            edit.read('config.ini')

            edit_deepl = edit["deepL"]
            edit_deepl["auth_key"] = values['-deepL_API-']

            with open('config.ini', 'w') as configfile:
                edit.write(configfile)
            window.close()
            config.read('config.ini')
            window = gui.main_window()
            config_deepl = config['deepL']
            gui.get_usage(window, config_deepl)

        if event == sg.WIN_CLOSED or event == "Exit":
            break

    window.close()


if __name__ == '__main__':
    main()

gui.py

import PySimpleGUI as sg
from static import font
import deepl

sg.theme('Reddit')


def main_window():
    toolbar_buttons = [[
        sg.Button('', image_filename='static/gear.png', key='-config-',
                  button_color=('#eeeeee', 'white'), pad=((300, 0), (0, 30))),
    ]]
    # ------------ メインウィンドウ作成 ------------
    left_col = [
        [sg.Text('翻訳支援アプリ', font=font.udp_l, justification='center', text_color='#483d8b')],
        [sg.Text('powered by', font=font.udp_s, text_color='#483d8b'),
         sg.Image(source='static/deepL_logo_ss.png')],
        [sg.Text('原文(日、英は自動判定します)', font=font.udp_m, pad=(0, 20))],
        [sg.Multiline('', key='-original_text-', font=font.udp_s, size=(35, 10))],
        [sg.Text('逆翻訳(DeepL翻訳⇨DeepL再翻訳)', font=font.udp_m, pad=(0, 20))],
        [sg.Multiline('', key='-back_trans_text-', font=font.udp_s, size=(35, 10))],
    ]

    right_col = [
        [sg.Frame('', toolbar_buttons, title_color='white',
                  vertical_alignment='t',
                  element_justification='right', border_width=0)],
        [sg.Text('DeepL翻訳(原文⇨DeepL翻訳))', justification='center', font=font.udp_m, pad=(50, 20))],
        [sg.Multiline('', key='-translated_text-', font=font.udp_s, size=(35, 10))],
        [sg.Button(image_filename='static/deepL_btn_s.png', key='-run_deepl-', pad=(120, 20))],
        [sg.Text('DeepL Usage', font=font.udp_m, pad=(120, 10))],
        [sg.Text('', key='-Char_cnt-', font=font.udp_s, pad=(100, 10))],
        [sg.ProgressBar(100, orientation='h', key='-usage_bar-', visible=True, size=(35, 20),
                        pad=(30, 10))]
    ]

    layout = [
        [sg.Column(left_col, element_justification='c'),
         sg.VSeperator(color='#eeeeee'),
         sg.Column(right_col, vertical_alignment='top')]
    ]

    return sg.Window("翻訳支援アプリ", layout, finalize=True)


def config_window(config):
    # ------------ Configウィンドウ作成 ------------

    config_layout = [
        [sg.T('DeepL設定', font=font.osk_l, justification='center', text_color='#483d8b',
              pad=(0, 10))],
        [sg.T('APIキー:', font=font.udp_s, size=(8, 1)),
         sg.Input(config['Auth_key'], password_char='*', key='-deepL_API-',
                  font=font.udp_s, size=(30, 1))],
        [sg.Button('更新', font=font.osk_s, key='-config_update-', size=(5, 1), pad=(180, 20))]
    ]
    return sg.Window("DeepL設定", config_layout, finalize=True)


def get_usage(window, config):
    count_result = deepl.char_cnt(config)
    if count_result is None:
        sg.popup('APIキーを確認して下さい')
    else:
        count_used = count_result['character_count']
        count_limit = count_result['character_limit']
        bar_used = count_used/count_limit * 100
        output_txt = str(count_used) + ' / ' + str(count_limit) + '文字'
        window['-usage_bar-'].update(bar_used)
        window['-Char_cnt-'].update(output_txt)

deepl.py

import json
from urllib.parse import urlencode
from urllib.request import Request
from urllib.request import urlopen
from urllib.error import HTTPError
import re


def translate(text, s_lang, t_lang, config):
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded; utf-8'
    }

    params = {
        'auth_key': config['Auth_key'],
        'text': text,
        'souce_lang': s_lang,
        'target_lang': t_lang
        # ,'tab_handling': tag_handling
    }

    req = Request(
        config['Translate_EP'],
        method='POST',
        data=urlencode(params).encode('utf-8'),
        headers=headers
    )

    try:
        with urlopen(req) as res:
            trans_result = json.loads(res.read().decode('utf-8'))            
            return trans_result['translations'][0]['text']            
    except HTTPError as e:
        print(e)


def char_cnt(config):
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded; utf-8'
    }

    params = {
        'auth_key': config['Auth_key'],
    }

    req = Request(
        config['Usage_EP'],
        method='POST',
        data=urlencode(params).encode('utf-8'),
        headers=headers
    )
    try:
        with urlopen(req) as res:
            cnt_result = json.loads(res.read().decode('utf-8'))
            return cnt_result

    except HTTPError as e:
        print(e)


def lang_set(text):
    # default setting
    lang = {'target': "EN", 'source': "JA"}
    if is_japanese(text) is not True:
        lang['target'] = "JA"
        lang['source'] = "EN"
    return lang


def is_japanese(text):
    return True if re.search(r'[ぁ-んァ-ン]', text) else False

config.ini

[deepL]
auth_key = ご自身のAPI認証キー
translate_ep = https://api-free.deepl.com/v2/translate
usage_ep = https://api-free.deepl.com/v2/usage




この記事が気に入ったらサポートをしてみませんか?