Skip to content

Commit

Permalink
refactor: utilize dataclass and dacite
Browse files Browse the repository at this point in the history
Signed-off-by: Jack Cherng <[email protected]>
  • Loading branch information
jfcherng committed Aug 13, 2022
1 parent 55ceba2 commit b9e1e6c
Show file tree
Hide file tree
Showing 99 changed files with 735 additions and 217 deletions.
13 changes: 1 addition & 12 deletions plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
# import all listeners and commands
from .commands.fanhuaji_convert import FanhuajiConvertCommand
from .commands.fanhuaji_convert_panel import FanhuajiConvertPanelCommand

__all__ = (
# ST: core
"plugin_loaded",
"plugin_unloaded",
# ST: commands
"FanhuajiConvertCommand",
"FanhuajiConvertPanelCommand",
)
from .commands import * # noqa: F401, F403


def plugin_loaded() -> None:
Expand Down
7 changes: 7 additions & 0 deletions plugin/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from .fanhuaji_convert import FanhuajiConvertCommand
from .fanhuaji_convert_panel import FanhuajiConvertPanelCommand

__all__ = (
"FanhuajiConvertCommand",
"FanhuajiConvertPanelCommand",
)
53 changes: 42 additions & 11 deletions plugin/commands/fanhuaji_convert.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from typing import Dict, Optional
from typing import Any, Dict, Optional

import sublime
import sublime_plugin

from ..constant import TEXT_DELIMITER
from ..fanhuaji import Fanhuaji
from ..functions import prepare_fanhuaji_convert_args
from ..log import msg
from ..settings import get_setting


class FanhuajiConvertCommand(sublime_plugin.TextCommand):
Expand All @@ -17,20 +16,52 @@ def is_visible(self) -> bool:
return self.is_enabled()

def run(self, edit: sublime.Edit, args: Optional[Dict] = None) -> None:
args = prepare_fanhuaji_convert_args(self.view, args)
args = self._prepare_fanhuaji_convert_args(self.view, args)

try:
result = Fanhuaji.convert(args)
except Exception as e:
sublime.error_message(msg(f"Failed to reach the server: {e}"))
sublime.error_message(msg(str(e)))
return

if int(result["code"]) != 0:
sublime.error_message(msg(f'Error message from the server: {result["msg"]}'))
if int(result.code) != 0:
sublime.error_message(msg(f"Error message from the server: {result.msg}"))
return

texts = result["data"]["text"].split(TEXT_DELIMITER)
region_text_pairs = tuple(zip(self.view.sel(), texts))

for region, text in reversed(region_text_pairs):
for region, text in zip(
reversed(self.view.sel()),
reversed(result.data.text.split(Fanhuaji.TEXT_DELIMITER)),
):
self.view.replace(edit, region, text)

@staticmethod
def _prepare_fanhuaji_convert_args(view: sublime.View, args: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
_args: Dict[str, Any] = get_setting("convert_params")

# 轉換模組
if "modules" in _args and isinstance(_args["modules"], dict):
_args["modules"] = sublime.encode_value(_args["modules"])

# 轉換前取代
if "userPreReplace" in _args and isinstance(_args["userPreReplace"], dict):
_args["userPreReplace"] = "\n".join(f"{old}={new}" for old, new in _args["userPreReplace"].items())

# 轉換後取代
if "userPostReplace" in _args and isinstance(_args["userPostReplace"], dict):
_args["userPostReplace"] = "\n".join(f"{old}={new}" for old, new in _args["userPostReplace"].items())

# 保護字詞
if "userProtectReplace" in _args and isinstance(_args["userProtectReplace"], list):
_args["userProtectReplace"] = "\n".join(_args["userProtectReplace"])

# 參數: API 全域
_args["apiKey"] = get_setting("api_key")
_args["prettify"] = False

# 參數: API convert 端點
_args["text"] = Fanhuaji.TEXT_DELIMITER.join(view.substr(region) for region in view.sel())
_args["diffEnable"] = False

_args.update(args or {})

return _args
14 changes: 7 additions & 7 deletions plugin/commands/fanhuaji_convert_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ def run(self) -> None:
self.window.show_quick_panel(
tuple(
sublime.QuickPanelItem(
trigger="{name_eng} - {name_chi}".format_map(converter),
annotation=converter["annotation"],
details=converter["details"],
kind=converter["st_kind"],
trigger=f"{converter.name_eng} - {converter.name_chi}",
annotation=converter.annotation,
details=converter.details,
kind=converter.st_kind,
)
for converter in Fanhuaji.converters
for converter in Fanhuaji.CONVERTERS
),
self.on_done,
)
Expand All @@ -23,13 +23,13 @@ def on_done(self, index: int) -> None:
if index == -1:
return

converter = Fanhuaji.converters[index]
converter = Fanhuaji.CONVERTERS[index]

self.window.run_command(
"fanhuaji_convert",
{
"args": {
"converter": converter["name_api"],
"converter": converter.name_api,
},
},
)
29 changes: 16 additions & 13 deletions plugin/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

import sublime

PLUGIN_NAME = __package__.partition(".")[0] # like "AutoSetSyntax"
PLUGIN_NAME = __package__.partition(".")[0]
"""Like `"AutoSetSyntax"`."""

ST_ARCH = sublime.arch() # like "x64"
ST_CHANNEL = sublime.channel() # like "dev"
ST_PLATFORM = sublime.platform() # like "windows"
ST_PLATFORM_ARCH = f"{ST_PLATFORM}_{ST_ARCH}" # like "windows_x64"
ST_VERSION = int(sublime.version()) # like 4113
PY_VERSION_FULL = sys.version # like "3.8.8 (default, Mar 10 2021, 13:30:47) [MSC v.1915 64 bit (AMD64)]"
PY_VERSION = PY_VERSION_FULL.partition(" ")[0] # like "3.8.8"

# The delimiter used to concat/split multiple selected text,
# so we could convert multiple text with only a single API call.
# This delimiter should be a extremely rarely used string.
TEXT_DELIMITER = r"\n\5\9\8\n"
ST_ARCH = sublime.arch()
"""Like `"x64"`."""
ST_CHANNEL = sublime.channel()
"""Like `"dev"`."""
ST_PLATFORM = sublime.platform()
"""Like `"windows"`."""
ST_PLATFORM_ARCH = f"{ST_PLATFORM}_{ST_ARCH}"
"""Like `"windows_x64"`."""
ST_VERSION = int(sublime.version())
"""Like `4113`."""
PY_VERSION_FULL = sys.version
"""Like `"3.8.8 (default, Mar 10 2021, 13:30:47) [MSC v.1915 64 bit (AMD64)]"`."""
PY_VERSION = PY_VERSION_FULL.partition(" ")[0]
"""Like `"3.8.8"`."""
207 changes: 115 additions & 92 deletions plugin/fanhuaji.py
Original file line number Diff line number Diff line change
@@ -1,115 +1,138 @@
from typing import Any, Dict, Tuple
from typing import Any, Dict

import sublime

from ..vendor import dacite, requests
from .constant import ST_PLATFORM_ARCH, ST_VERSION
from .libs import requests
from .log import print_msg
from .settings import get_setting
from .types import TD_ApiConvertResponse, TD_ConverterInfo
from .types import ApiConvertResponse, ConverterInfo

HTTP_HEADERS = {
"user-agent": f"Sublime Text {ST_VERSION} ({ST_PLATFORM_ARCH}) Fanhuaji",
}


class FanhuajiApiUrl:
@classmethod
def base_url(cls) -> str:
return get_setting("api_server").rstrip("/")

@classmethod
def convert(cls) -> str:
return f"{cls.base_url()}/convert"

@classmethod
def service_info(cls) -> str:
return f"{cls.base_url()}/service-info"


class Fanhuaji:
converters: Tuple[TD_ConverterInfo, ...] = (
{
"name_api": "Simplified",
"name_eng": "Simplified",
"name_chi": "简体化",
"details": "将文字转换为简体。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_ORANGISH, "简", ""),
},
{
"name_api": "Traditional",
"name_eng": "Traditional",
"name_chi": "繁體化",
"details": "將文字轉換為繁體。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_ORANGISH, "繁", ""),
},
{
"name_api": "China",
"name_eng": "China Localization",
"name_chi": "中国化",
"details": "将文字转换为简体,并使用中国地区的词语修正。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_CYANISH, "中", ""),
},
{
"name_api": "Hongkong",
"name_eng": "Hongkong Localization",
"name_chi": "香港化",
"details": "將文字轉換為繁體,並使用香港地區的詞語修正。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_CYANISH, "港", ""),
},
{
"name_api": "Taiwan",
"name_eng": "Taiwan Localization",
"name_chi": "台灣化",
"details": "將文字轉換為繁體,並使用台灣地區的詞語修正。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_CYANISH, "台", ""),
},
{
"name_api": "Pinyin",
"name_eng": "Pinyin",
"name_chi": "拼音化",
"details": "將文字轉為拼音。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_GREENISH, "拼", ""),
},
{
"name_api": "Bopomofo",
"name_eng": "Bopomofo",
"name_chi": "注音化",
"details": "將文字轉為注音。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_GREENISH, "注", ""),
},
{
"name_api": "Mars",
"name_eng": "Mars",
"name_chi": "火星化",
"details": "將文字轉換為繁體火星文。",
"annotation": "",
"st_kind": (sublime.KIND_ID_COLOR_GREENISH, "火", ""),
},
{
"name_api": "WikiSimplified",
"name_eng": "Simplified (Wikipeida)",
"name_chi": "维基简体化",
"details": "只使用维基百科的词库将文字转换为简体。",
"annotation": "(少用)",
"st_kind": (sublime.KIND_ID_COLOR_LIGHT, "简", ""),
},
{
"name_api": "WikiTraditional",
"name_eng": "Traditional (Wikipeida)",
"name_chi": "維基繁體化",
"details": "只使用維基百科的詞庫將文字轉換為繁體。",
"annotation": "(少用)",
"st_kind": (sublime.KIND_ID_COLOR_LIGHT, "繁", ""),
},
CONVERTERS = (
ConverterInfo(
name_api="Simplified",
name_eng="Simplified Chinese",
name_chi="简体化",
details="将文字转换为简体。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_ORANGISH, "简", ""),
),
ConverterInfo(
name_api="Traditional",
name_eng="Traditional Chinese",
name_chi="繁體化",
details="將文字轉換為繁體。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_ORANGISH, "繁", ""),
),
ConverterInfo(
name_api="China",
name_eng="China Localization",
name_chi="中国化",
details="将文字转换为简体,并使用中国地区的词语修正。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_CYANISH, "中", ""),
),
ConverterInfo(
name_api="Hongkong",
name_eng="Hongkong Localization",
name_chi="香港化",
details="將文字轉換為繁體,並使用香港地區的詞語修正。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_CYANISH, "港", ""),
),
ConverterInfo(
name_api="Taiwan",
name_eng="Taiwan Localization",
name_chi="台灣化",
details="將文字轉換為繁體,並使用台灣地區的詞語修正。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_CYANISH, "台", ""),
),
ConverterInfo(
name_api="Pinyin",
name_eng="Pinyin",
name_chi="拼音化",
details="將文字轉為拼音。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_GREENISH, "拼", ""),
),
ConverterInfo(
name_api="Bopomofo",
name_eng="Bopomofo",
name_chi="注音化",
details="將文字轉為注音。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_GREENISH, "注", ""),
),
ConverterInfo(
name_api="Mars",
name_eng="Mars",
name_chi="火星化",
details="將文字轉換為繁體火星文。",
annotation="",
st_kind=(sublime.KIND_ID_COLOR_GREENISH, "火", ""),
),
ConverterInfo(
name_api="WikiSimplified",
name_eng="Simplified Chinese (Wikipeida)",
name_chi="维基简体化",
details="只使用维基百科的词库将文字转换为简体。",
annotation="(少用)",
st_kind=(sublime.KIND_ID_COLOR_LIGHT, "简", ""),
),
ConverterInfo(
name_api="WikiTraditional",
name_eng="Traditional Chinese (Wikipeida)",
name_chi="維基繁體化",
details="只使用維基百科的詞庫將文字轉換為繁體。",
annotation="(少用)",
st_kind=(sublime.KIND_ID_COLOR_LIGHT, "繁", ""),
),
)

TEXT_DELIMITER = r"\n\5\9\8\n"
"""
The delimiter used to concat/split multiple selected text,
so we could convert multiple text with only a single API call.
This delimiter should be a extremely rarely used string.
"""

@classmethod
def convert(cls, args: Dict[str, Any]) -> TD_ApiConvertResponse:
def convert(cls, args: Dict[str, Any]) -> ApiConvertResponse:
if get_setting("debug"):
print_msg(f"Request {args = }")

url = get_setting("api_server") + "/convert"
verify_ssl = bool(get_setting("ssl_cert_verification"))

try:
response = requests.post(url, data=args, headers=HTTP_HEADERS, verify=verify_ssl)
response: requests.Response = requests.post(
url=FanhuajiApiUrl.convert(),
data=args,
headers=HTTP_HEADERS,
verify=bool(get_setting("ssl_cert_verification")),
)
except requests.exceptions.ConnectionError as e:
raise RuntimeError(f"Failed to reach the server: {e}")
raise RuntimeError(f"Failed to reach the server: {e}") from e
except requests.exceptions.RequestException as e:
raise RuntimeError(f"Request exception: {e}")
raise RuntimeError(f"Request exception: {e}") from e

return sublime.decode_value(response.text)
return dacite.from_dict(ApiConvertResponse, sublime.decode_value(response.text))
Loading

0 comments on commit b9e1e6c

Please sign in to comment.