99import tqdm
1010from typing import IO , Dict , Optional , Tuple
1111import zipfile
12+ from datetime import datetime
1213
1314from shutil import which
1415from urllib .parse import urljoin
2627
2728
2829# Get download host from environment or default.
29- BASE_URL = os .environ .get ('LTP_DOWNLOAD_HOST' , 'https://www.languagetool.org/download/' )
30- FILENAME = 'LanguageTool-{version}.zip'
30+ BASE_URL_SNAPSHOT = os .environ .get ('LTP_DOWNLOAD_HOST_SNAPSHOT' , 'https://internal1.languagetool.org/snapshots/' )
31+ FILENAME_SNAPSHOT = 'LanguageTool-{version}-snapshot.zip'
32+ BASE_URL_RELEASE = os .environ .get ('LTP_DOWNLOAD_HOST_RELEASE' , 'https://www.languagetool.org/download/' )
33+ FILENAME_RELEASE = 'LanguageTool-{version}.zip'
3134
32- LTP_DOWNLOAD_VERSION = '6.5'
35+ LTP_DOWNLOAD_VERSION = 'latest'
36+ LT_SNAPSHOT_CURRENT_VERSION = '6.7-SNAPSHOT'
3337
3438JAVA_VERSION_REGEX = re .compile (
3539 r'^(?:java|openjdk) version "(?P<major1>\d+)(|\.(?P<major2>\d+)\.[^"]+)"' ,
@@ -65,16 +69,15 @@ def parse_java_version(version_text: str) -> Tuple[int, int]:
6569 return (major1 , major2 )
6670
6771
68- def confirm_java_compatibility () -> bool :
72+ def confirm_java_compatibility (language_tool_version : Optional [ str ] = LTP_DOWNLOAD_VERSION ) -> None :
6973 """
7074 Confirms if the installed Java version is compatible with language-tool-python.
71- This function checks if Java is installed and verifies that the major version is at least 8.
75+ This function checks if Java is installed and verifies that the major version is at least 8 or 17 (depending on the LanguageTool version) .
7276 It raises an error if Java is not installed or if the version is incompatible.
7377
78+ :param language_tool_version: The version of LanguageTool to check compatibility for.
7479 :raises ModuleNotFoundError: If no Java installation is detected.
75- :raises SystemError: If the detected Java version is less than 8.
76- :return: True if the Java version is compatible.
77- :rtype: bool
80+ :raises SystemError: If the detected Java version is less than the required version.
7881 """
7982
8083 java_path = which ('java' )
@@ -91,15 +94,12 @@ def confirm_java_compatibility() -> bool:
9194 major_version , minor_version = parse_java_version (output )
9295 # Some installs of java show the version number like `14.0.1`
9396 # and others show `1.14.0.1`
94- # (with a leading 1). We want to support both,
95- # as long as the major version is >= 8.
97+ # (with a leading 1). We want to support both.
9698 # (See softwareengineering.stackexchange.com/questions/175075/why-is-java-version-1-x-referred-to-as-java-x)
97- if major_version == 1 and minor_version >= 8 :
98- return True
99- elif major_version >= 8 :
100- return True
101- else :
102- raise SystemError (f'Detected java { major_version } .{ minor_version } . LanguageTool requires Java >= 8.' )
99+ if language_tool_version != 'latest' and (language_tool_version < '6.6' or datetime .strptime (language_tool_version , '%Y%m%d' ) < datetime .strptime ('2025-03-27' , '%Y-%m-%d' )) and (major_version == 1 and minor_version < 8 ) or (major_version < 8 ):
100+ raise SystemError (f'Detected java { major_version } .{ minor_version } . LanguageTool requires Java >= 8 for version { language_tool_version } .' )
101+ elif (major_version == 1 and minor_version < 17 ) or (major_version < 17 ):
102+ raise SystemError (f'Detected java { major_version } .{ minor_version } . LanguageTool requires Java >= 17 for version { language_tool_version } .' )
103103
104104
105105def get_common_prefix (z : zipfile .ZipFile ) -> Optional [str ]:
@@ -135,7 +135,7 @@ def http_get(url: str, out_file: IO[bytes], proxies: Optional[Dict[str, str]] =
135135 total = int (content_length ) if content_length is not None else None
136136 if req .status_code == 404 :
137137 raise PathError (f'Could not find at URL { url } . The given version may not exist or is no longer available.' )
138- version = re . search ( r'(\d+\.\d+)' , url ). group ( 1 )
138+ version = url . split ( '/' )[ - 1 ]. split ( '-' )[ 1 ]. replace ( '-snapshot' , '' ). replace ( '.zip' , '' )
139139 progress = tqdm .tqdm (unit = "B" , unit_scale = True , total = total ,
140140 desc = f'Downloading LanguageTool { version } ' )
141141 for chunk in req .iter_content (chunk_size = 1024 ):
@@ -196,7 +196,7 @@ def download_lt(language_tool_version: Optional[str] = LTP_DOWNLOAD_VERSION) ->
196196 :raises AssertionError: If the download folder is not a directory.
197197 """
198198
199- confirm_java_compatibility ()
199+ confirm_java_compatibility (language_tool_version )
200200
201201 download_folder = get_language_tool_download_path ()
202202
@@ -213,9 +213,15 @@ def download_lt(language_tool_version: Optional[str] = LTP_DOWNLOAD_VERSION) ->
213213
214214 if language_tool_version :
215215 version = language_tool_version
216- filename = FILENAME .format (version = version )
217- language_tool_download_url = urljoin (BASE_URL , filename )
216+ if re .match (r'^\d+\.\d+$' , version ):
217+ filename = FILENAME_RELEASE .format (version = version )
218+ language_tool_download_url = urljoin (BASE_URL_RELEASE , filename )
219+ else :
220+ filename = FILENAME_SNAPSHOT .format (version = version )
221+ language_tool_download_url = urljoin (BASE_URL_SNAPSHOT , filename )
218222 dirname , _ = os .path .splitext (filename )
223+ if version == "latest" :
224+ dirname = f"LanguageTool-{ LT_SNAPSHOT_CURRENT_VERSION } "
219225 extract_path = os .path .join (download_folder , dirname )
220226
221227 if extract_path in old_path_list :
0 commit comments