Skip to content

Commit f3093f2

Browse files
singh-lokendrasushain97
authored andcommitted
Add setup.py (#38)
* Installation script for windows platform * Removed Dependency on Apertium Bash helper script to make compatible with windows * Modifying the environment varible PATH for the current process only * Update the location of Language files for Windows Environment by checking at default installation path * Use installation.py to install on windows platform * Fix: Windows Installation Check * Completed the incomplete comment * Combine the import statements to improve readability * Renamed * Implemented changes suggested in class renamed: class Installation -> Installer added: object variable _language_link renamed: main() -> install_apertium_windows() * Added: Logging Module * Added: tempfile module to create temp directory * Removed: Multiple spaces after operator * Added: Function type annotation * Replaced: fstring with format method to support previous python version * Implemented changes suggested modified: opening README.MD removed: redundant setup_requires added: python_requirement >= 3.4 * Added: Function type annotation * Added: Newline after stdlib * Implemented changes suggested Removed: from os import path Edited: Process' Path comment * Implemented changes suggested Sorted the import libraries Added: TODO variables * Implemented changes suggested Sorted the import statements Edited: import shutil Removed: from os import path Added: class variable with base link for downloading Edited: with open instead of open Edited: logging messages Removed: blank lines around class definition Renamed: mode_editor() -> edit_modes() Removed: Redundant if __name__ * Implemented changes suggested Renamed: download_language_data() -> download_package() Edited: contructor parameter from tuple to list * added: class method install to call all the relevant methods * Added: python setup.py test * Added: python setup.py install This should verify the installation process on Appveyor * Replaced: os.putenv, os.getenv os.environ * Added: ';' while updating path values generate logs while updating path * Undo all the changes done in utils.py * Add the Apertium Binaries to Process' PATH while importing module * Replaced: Single quotes with Double quotes in Docstring * Implemented changes suggested - Replaced: Single Quotes with Double Quotes - Removed: Redundant Blank line - Fixed: type annotation comment for Installer._download_zip() - Fixed: Typo in comment - Renamed: zip_obj -> zip_file - Replaced: download_dir, extract_path -> self._download_path, self._install_path - Removed: redundant argument 'download_dir' from Installer._download_zip() - Modified: Use Installer.base_link as download link for apertium_windows - Replaced: file with f, as 'file' messes up with syntax highlighting - Removed: Redundant read mode while opening a file - Renamed: Installer.install() -> Installer.install_windows() * Implemented changes suggested - Added: TODO values - Removed: redundant spaces around operator while calling setup() * Removed redundant code and renamed class method - Removed: Redundant removal of single quotes from .mode files - Renamed: Installer methods to suggest internal usage * Replaced: ';' with os.pathsep * Implemented changes suggested - Replaced: '\' with os.sep - Renamed: Installer._download_zip() -> Installer._download_zips() - Removed: New Line at start of Installer._download_zips() - Modified: Installer.base_link is modified in _download_zips() - Modified: Used 'with' while opening zip_file in _download_zips() - Raise ValueError when setup isn't run on Windows Platform - Modified: Send logs to stdout * Implemented changes suggested - Removed: Redundant ZipFile.close method(with context manager) - Merged Lines: key and value in a single line, in apertium_windows{}
1 parent 3638ecd commit f3093f2

File tree

5 files changed

+171
-2
lines changed

5 files changed

+171
-2
lines changed

.appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ install:
3434
- python --version
3535
- python -c "import sys,platform,struct; print(sys.platform, platform.machine(), struct.calcsize('P') * 8, )"
3636
- pip install -r requirements-dev.txt
37+
- python setup.py install
3738
build: false
3839
test_script:
3940
- coverage run -m unittest --verbose --buffer tests

apertium/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import platform
2+
import os
3+
14
from apertium.mode_search import search_path
25
from apertium.analysis import Analyzer, analyze # noqa: F401
36
from apertium.generation import Generator, generate # noqa: F401
@@ -38,9 +41,33 @@ def append_pair_path(pair_path): # type: (str) -> None
3841
_update_modes(pair_path)
3942

4043

44+
def append_pair_path_windows(): # type (None) -> None
45+
if platform.system() == 'Windows':
46+
install_path = os.getenv('LOCALAPPDATA')
47+
apertium_lang_path = \
48+
os.path.join(install_path, 'apertium-all-dev', 'share', 'apertium')
49+
if os.path.isdir(apertium_lang_path):
50+
append_pair_path(apertium_lang_path)
51+
52+
53+
def update_path_windows():
54+
"""Adding the Apertium Binaries to Process' PATH"""
55+
56+
if platform.system() == 'Windows':
57+
install_path = os.environ['LOCALAPPDATA']
58+
current = os.environ['path']
59+
60+
apertium_path = os.path.join(install_path, 'apertium-all-dev', 'bin')
61+
if os.path.isdir(apertium_path):
62+
update_path = '{}{}{}{}'.format(current, os.pathsep, apertium_path, os.pathsep)
63+
os.environ['path'] = update_path
64+
65+
4166
pair_paths = ['/usr/share/apertium', '/usr/local/share/apertium']
4267
analyzers = {} # type: Dict[str, Tuple[str, str]]
4368
generators = {} # type: Dict[str, Tuple[str, str]]
4469
pairs = {} # type: Dict[str, str]
4570
for pair_path in pair_paths:
4671
_update_modes(pair_path)
72+
append_pair_path_windows()
73+
update_path_windows()

apertium/analysis/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ def analyze(self, in_text, formatting='txt'): # type: (Analyzer, str, str) -> L
6060
Returns:
6161
List[LexicalUnit]
6262
"""
63-
commands = [['apertium', '-d', self.path, '-f', formatting, self.mode]]
64-
result = execute(in_text, commands)
63+
apertium_des = execute(in_text, [['apertium-des{}'.format(formatting), '-n']])
64+
result = execute(apertium_des, self._get_commands())
6565
return self._postproc_text(result)
6666

6767

installer.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import logging
2+
import os
3+
import platform
4+
import shutil
5+
import tempfile
6+
from distutils.dir_util import copy_tree
7+
from urllib.request import urlretrieve
8+
from zipfile import ZipFile
9+
10+
class Installer:
11+
base_link = "http://apertium.projectjj.com/{}"
12+
13+
def __init__(self, languages): # type: (Installer, list) -> None
14+
self._install_path = os.getenv("LOCALAPPDATA")
15+
self._apertium_path = os.path.join(self._install_path, "apertium-all-dev")
16+
self._download_path = tempfile.mkdtemp()
17+
self._languages = languages
18+
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.DEBUG)
19+
self._logger = logging.getLogger()
20+
self._logger.setLevel(logging.DEBUG)
21+
22+
def _download_zips(self, download_files, extract_path): # type: (Installer, dict, str) -> None
23+
for zip_name, zip_link in download_files.items():
24+
zip_download_path = os.path.join(self._download_path, zip_name)
25+
urlretrieve(Installer.base_link.format(zip_link), filename=zip_download_path)
26+
self._logger.info("%s download completed", zip_name)
27+
28+
# Extract the zip
29+
with ZipFile(zip_download_path) as zip_file:
30+
zip_file.extractall(path=extract_path)
31+
self._logger.info("%s Extraction completed", zip_name)
32+
os.remove(zip_download_path)
33+
self._logger.info("%s removed", zip_name)
34+
35+
def _download_apertium_windows(self): # type: (Installer) -> None
36+
"""Installs Apertium-all-dev to %localappdata%"""
37+
38+
apertium_windows = {
39+
"apertium-all-dev.zip": "/win64/nightly/apertium-all-dev.zip",
40+
}
41+
42+
self._download_zips(apertium_windows, self._install_path)
43+
44+
def _download_package(self): # type: (Installer) -> None
45+
"""Installs Language Data to Apertium"""
46+
47+
if platform.system() == "Windows":
48+
zip_path = "win32/nightly/data.php?zip="
49+
else:
50+
raise ValueError("Installation for {} is not supported".format(platform.system()))
51+
language_zip = {}
52+
for curr_lang in self._languages:
53+
language_zip[curr_lang] = zip_path + curr_lang
54+
55+
self._download_zips(language_zip, self._download_path)
56+
57+
# move the extracted files to desired location
58+
lang_data_path = os.path.join(self._download_path, "usr", "share", "apertium")
59+
60+
self._logger.info("Copying Language Data to Apertium")
61+
for directory in os.listdir(lang_data_path):
62+
source = os.path.join(lang_data_path, directory)
63+
destination = os.path.join(self._apertium_path, "share", "apertium", directory)
64+
copy_tree(source, destination)
65+
self._logger.info("%s -> %s", source, destination)
66+
67+
shutil.rmtree(os.path.join(self._download_path, "usr"))
68+
69+
def _edit_modes(self): # type: (Installer) -> None
70+
"""The mode files need to be modified before being used on Windows System
71+
72+
1. Replace /usr/share with %localappdata%\apertium-all-dev\share
73+
2. Replace "/" with "\" to make path compatible with Windows System
74+
"""
75+
76+
# List of Mode Files
77+
mode_path = os.path.join(self._apertium_path, "share", "apertium", "modes")
78+
for f in os.listdir(mode_path):
79+
if os.path.isfile(os.path.join(mode_path, f)) and f.endswith(".mode"):
80+
self._logger.info("Editing mode %s ", f)
81+
with open(os.path.join(mode_path, f)) as infile:
82+
line = infile.read()
83+
84+
contents = line.split(" ")
85+
# Editing mode file to be compatible with windows platform
86+
for i, t in enumerate(contents):
87+
if len(t) > 2 and t[0] == "'" and t[1] == "/":
88+
t = t.replace("/", os.sep)
89+
t = t.replace(r"\usr", self._apertium_path)
90+
contents[i] = t
91+
line = " ".join(contents)
92+
with open(os.path.join(mode_path, f), "w") as outfile:
93+
outfile.write(line)
94+
outfile.close()
95+
96+
def install_windows(self):
97+
self._download_apertium_windows()
98+
self._download_package()
99+
self._edit_modes()
100+
101+
def install_apertium_windows():
102+
"""Download ApertiumWin64 and Move to %localappdata%"""
103+
104+
if platform.system() == "Windows":
105+
p = Installer(["apertium-eng", "apertium-en-es"])
106+
p.install_windows()

setup.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from atexit import register
2+
from os import path
3+
from setuptools import setup, find_packages
4+
from setuptools.command.install import install
5+
6+
import installer
7+
8+
9+
class PostInstallCommand(install):
10+
def __init__(self, *args, **kwargs):
11+
super(PostInstallCommand, self).__init__(*args, **kwargs)
12+
register(self._post_install)
13+
14+
@staticmethod
15+
def _post_install():
16+
installer.install_apertium_windows()
17+
18+
19+
setup(
20+
name='apertium-python',
21+
# TODO: Add version description, keywords, author, author_email
22+
license='GNU General Public License v3.0 ',
23+
long_description=open(path.join(path.abspath(path.dirname(__file__)), 'README.md')).read(),
24+
long_description_content_type='text/markdown; charset=UTF-8',
25+
url='https://github.com/apertium/apertium-python',
26+
python_requires='>=3.4',
27+
install_requires=[
28+
'apertium-streamparser==5.0.2',
29+
],
30+
test_suite='tests',
31+
packages=find_packages(exclude=['tests']),
32+
cmdclass={
33+
'install': PostInstallCommand,
34+
},
35+
)

0 commit comments

Comments
 (0)