Skip to content

Commit

Permalink
Merge pull request #139 from nidhaloff/refactoring
Browse files Browse the repository at this point in the history
Refactoring
  • Loading branch information
nidhaloff authored Mar 9, 2022
2 parents 721a708 + 7a05cd7 commit 784f56a
Show file tree
Hide file tree
Showing 36 changed files with 971 additions and 650 deletions.
8 changes: 3 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,13 @@ clean-test: ## remove test and coverage artifacts
rm -fr htmlcov/
rm -fr .pytest_cache

lint: ## check style with flake8
flake8 deep_translator tests
format: ## format with black
poetry run isort .
poetry run black deep_translator tests

test: ## run tests quickly with the default Python
pytest

test-all: ## run tests on every Python version with tox
tox

coverage: ## check code coverage quickly with the default Python
coverage run --source deep_translator -m pytest
coverage report -m
Expand Down
28 changes: 14 additions & 14 deletions deep_translator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
"""Top-level package for Deep Translator"""

from .google import GoogleTranslator
from .pons import PonsTranslator
from .linguee import LingueeTranslator
from .mymemory import MyMemoryTranslator
from .yandex import YandexTranslator
from .qcri import QcriTranslator
from .deepl import DeeplTranslator
from .detection import single_detection, batch_detection
from .microsoft import MicrosoftTranslator
from .papago import PapagoTranslator
from .libre import LibreTranslator
from deep_translator.deepl import DeeplTranslator
from deep_translator.detection import batch_detection, single_detection
from deep_translator.google import GoogleTranslator
from deep_translator.libre import LibreTranslator
from deep_translator.linguee import LingueeTranslator
from deep_translator.microsoft import MicrosoftTranslator
from deep_translator.mymemory import MyMemoryTranslator
from deep_translator.papago import PapagoTranslator
from deep_translator.pons import PonsTranslator
from deep_translator.qcri import QcriTranslator
from deep_translator.yandex import YandexTranslator

__author__ = """Nidhal Baccouri"""
__email__ = 'nidhalbacc@gmail.com'
__version__ = '1.7.1'
__email__ = "nidhalbacc@gmail.com"
__version__ = "1.7.1"

__all__ = [
"GoogleTranslator",
Expand All @@ -28,5 +28,5 @@
"LibreTranslator",
"PapagoTranslator",
"single_detection",
"batch_detection"
"batch_detection",
]
3 changes: 1 addition & 2 deletions deep_translator/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

from .cli import CLI
from deep_translator.cli import CLI


def main():
Expand Down
59 changes: 35 additions & 24 deletions deep_translator/base.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
"""base translator class"""

from .constants import GOOGLE_LANGUAGES_TO_CODES
from .exceptions import InvalidSourceOrTargetLanguage
from abc import ABC, abstractmethod
from typing import List, Optional, Union

from deep_translator.constants import GOOGLE_LANGUAGES_TO_CODES
from deep_translator.exceptions import InvalidSourceOrTargetLanguage


class BaseTranslator(ABC):
"""
Abstract class that serve as a base translator for other different translators
"""
def __init__(self,
base_url=None,
source="auto",
target="en",
payload_key=None,
element_tag=None,
element_query=None,
languages=None,
**url_params):

def __init__(
self,
base_url: str,
languages: dict = GOOGLE_LANGUAGES_TO_CODES,
source: str = "auto",
target: str = "en",
payload_key: Optional[str] = None,
element_tag: Optional[str] = None,
element_query: Optional[dict] = None,
**url_params
):
"""
@param source: source language to translate from
@param target: target language to translate to
"""
self._base_url = base_url
self.languages: dict = GOOGLE_LANGUAGES_TO_CODES if not languages else languages
self.supported_languages: list = list(self.languages.keys())
self.languages = languages
self.supported_languages = list(self.languages.keys())
if not source:
raise InvalidSourceOrTargetLanguage(source)
if not target:
Expand All @@ -47,44 +52,50 @@ def _map_language_to_code(self, *languages):
@return: mapped value of the language or raise an exception if the language is not supported
"""
for language in languages:
if language in self.languages.values() or language == 'auto':
if language in self.languages.values() or language == "auto":
yield language
elif language in self.languages.keys():
yield self.languages[language]

def _same_source_target(self):
def _same_source_target(self) -> bool:
return self._source == self._target

def get_supported_languages(self, as_dict=False, **kwargs):
def get_supported_languages(
self, as_dict: bool = False, **kwargs
) -> Union[list, dict]:
"""
return the supported languages by the google translator
return the supported languages by the Google translator
@param as_dict: if True, the languages will be returned as a dictionary mapping languages to their abbreviations
@return: list or dict
"""
return self.supported_languages if not as_dict else self.languages

def is_language_supported(self, language, **kwargs):
def is_language_supported(self, language: str, **kwargs) -> bool:
"""
check if the language is supported by the translator
@param language: a string for 1 language
@return: bool or raise an Exception
"""
if language == 'auto' or language in self.languages.keys() or language in self.languages.values():
if (
language == "auto"
or language in self.languages.keys()
or language in self.languages.values()
):
return True
else:
return False

@abstractmethod
def translate(self, text, **kwargs):
def translate(self, text: str, **kwargs) -> str:
"""
translate a text using a translator under the hood and return the translated text
@param text: text to translate
@param kwargs: additional arguments
@return: str
"""
return NotImplemented('You need to implement the translate method!')
return NotImplemented("You need to implement the translate method!")

def _translate_file(self, path, **kwargs):
def _translate_file(self, path: str, **kwargs) -> str:
"""
translate directly from file
@param path: path to the target file
Expand All @@ -93,13 +104,13 @@ def _translate_file(self, path, **kwargs):
@return: str
"""
try:
with open(path, 'r', encoding='utf-8') as f:
with open(path, "r", encoding="utf-8") as f:
text = f.read().strip()
return self.translate(text)
except Exception as e:
raise e

def _translate_batch(self, batch=None, **kwargs):
def _translate_batch(self, batch: List[str], **kwargs) -> List[str]:
"""
translate a list of texts
@param batch: list of texts you want to translate
Expand Down
98 changes: 58 additions & 40 deletions deep_translator/cli.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,94 @@
"""Console script for deep_translator."""
import argparse
from .engines import __engines__
from typing import Optional

from deep_translator.engines import __engines__


class CLI(object):
translators_dict = __engines__
translator = None

def __init__(self, custom_args=None):
def __init__(self, custom_args: Optional[list] = None):
self.custom_args = custom_args
self.args = self.parse_args()
translator_class = self.translators_dict.get(self.args.translator, None)
if not translator_class:
raise Exception(f"Translator {self.args.translator} is not supported."
f"Supported translators: {list(self.translators_dict.keys())}")
self.translator = translator_class(source=self.args.source, target=self.args.target)
raise Exception(
f"Translator {self.args.translator} is not supported."
f"Supported translators: {list(self.translators_dict.keys())}"
)
self.translator = translator_class(
source=self.args.source, target=self.args.target
)

def translate(self):
def translate(self) -> None:
"""
function used to provide translations from the parsed terminal arguments
@return: None
"""
res = self.translator.translate(self.args.text)
print("Translation from {} to {}".format(self.args.source, self.args.target))
print(f"Translation from {self.args.source} to {self.args.target}")
print("-" * 50)
print("Translation result: {}".format(res))
print(f"Translation result: {res}")

def get_supported_languages(self):
def get_supported_languages(self) -> None:
"""
function used to return the languages supported by the translator service from the parsed terminal arguments
@return: None
"""

translator_supported_languages = self.translator.get_supported_languages(as_dict=True)
print(f'Languages supported by \'{self.args.translator}\' are :\n')
translator_supported_languages = self.translator.get_supported_languages(
as_dict=True
)
print(f"Languages supported by '{self.args.translator}' are :\n")
print(translator_supported_languages)

def parse_args(self):
def parse_args(self) -> argparse.Namespace:
"""
function responsible for parsing terminal arguments and provide them for further use in the translation process
"""
parser = argparse.ArgumentParser(add_help=True,
description="Official CLI for deep-translator",
usage="dt --help")
parser = argparse.ArgumentParser(
add_help=True,
description="Official CLI for deep-translator",
usage="dt --help",
)

parser.add_argument('--translator',
'-trans',
default='google',
type=str,
help="name of the translator you want to use")
parser.add_argument('--source',
'-src',
default='auto',
type=str,
help="source language to translate from")
parser.add_argument('--target',
'-tg',
type=str,
help="target language to translate to")
parser.add_argument('--text',
'-txt',
type=str,
help="text you want to translate")
parser.add_argument('--languages',
'-lang',
action='store_true',
help="all the languages available with the translator"
"Run the command deep_translator -trans <translator service> -lang")
parsed_args = parser.parse_args(self.custom_args) if self.custom_args else parser.parse_args()
parser.add_argument(
"--translator",
"-trans",
default="google",
type=str,
help="name of the translator you want to use",
)
parser.add_argument(
"--source",
"-src",
default="auto",
type=str,
help="source language to translate from",
)
parser.add_argument(
"--target", "-tg", type=str, help="target language to translate to"
)
parser.add_argument(
"--text", "-txt", type=str, help="text you want to translate"
)
parser.add_argument(
"--languages",
"-lang",
action="store_true",
help="all the languages available with the translator"
"Run the command deep_translator -trans <translator service> -lang",
)
parsed_args = (
parser.parse_args(self.custom_args)
if self.custom_args
else parser.parse_args()
)
return parsed_args

def run(self):
def run(self) -> None:
if self.args.languages:
self.get_supported_languages()
else:
Expand Down
Loading

0 comments on commit 784f56a

Please # to comment.