Warning, file /sdk/pology/sieve/check_grammar.py was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 # -*- coding: UTF-8 -*- 0002 0003 """ 0004 Check language of translation using LanguageTool. 0005 0006 Documented in C{doc/user/sieving.docbook}. 0007 0008 @author: Sébastien Renard <sebastien.renard@digitalfox.org> 0009 @license: GPLv3 0010 """ 0011 0012 from http.client import HTTPConnection 0013 import socket 0014 import sys 0015 from urllib.parse import urlencode 0016 from xml.dom.minidom import parseString 0017 0018 from pology import _, n_ 0019 from pology.colors import cjoin 0020 from pology.msgreport import report_msg_to_lokalize, warning_on_msg 0021 from pology.report import report, warning 0022 from pology.sieve import SieveError, SieveCatalogError 0023 from pology.sieve import add_param_lang, add_param_accel, add_param_markup 0024 from pology.sieve import add_param_filter 0025 from pology.getfunc import get_hook_ireq 0026 from pology.sieve import add_param_poeditors 0027 0028 0029 _REQUEST="/?language=%s&disabled=HUNSPELL_RULE&%s" 0030 0031 def setup_sieve (p): 0032 0033 p.set_desc(_("@info sieve discription", 0034 "Check language of translation using LanguageTool." 0035 "\n\n" 0036 "LanguageTool (http://www.languagetool.org) is an open source " 0037 "language checker, which may be used as a standalone application, " 0038 "or in server-client mode. " 0039 "This sieve runs in client-server mode, so make sure Language Tool " 0040 "is running before this sieve is run." 0041 )) 0042 0043 add_param_lang(p) 0044 add_param_accel(p) 0045 add_param_markup(p) 0046 add_param_filter(p, 0047 intro=_("@info sieve parameter discription", 0048 "The F1A or F3A/C hook through which to filter the translation " 0049 "before passing it to grammar checking." 0050 )) 0051 p.add_param("host", str, defval="localhost", 0052 metavar=_("@info sieve parameter value placeholder", "NAME"), 0053 desc=_("@info sieve parameter discription", 0054 "Name of the host where the server is running." 0055 )) 0056 p.add_param("port", str, defval="8081", 0057 metavar=_("@info sieve parameter value placeholder", "NUMBER"), 0058 desc=_("@info sieve parameter discription", 0059 "TCP port on the host which server uses to listen for queries." 0060 )) 0061 0062 add_param_poeditors(p) 0063 0064 0065 class Sieve (object): 0066 0067 def __init__ (self, params): 0068 0069 self.nmatch = 0 # Number of match for finalize 0070 self.connection=None # Connection to LanguageTool server 0071 0072 self.setLang=params.lang 0073 self.setAccel=params.accel 0074 self.setMarkup=params.markup 0075 self.lokalize = params.lokalize 0076 0077 # LanguageTool server parameters. 0078 host=params.host 0079 port=params.port 0080 #TODO: autodetect tcp port by reading LanguageTool config file if host is localhost 0081 0082 # As LT server does not seem to read disabled rules from his config file, we manage exception here 0083 #TODO: investigate deeper this problem and make a proper bug report to LT devs. 0084 self.disabledRules=["UPPERCASE_SENTENCE_START","COMMA_PARENTHESIS_WHITESPACE"] 0085 0086 # Create connection to the LanguageTool server 0087 self.connection=HTTPConnection(host, port) 0088 0089 self.pfilters = [[get_hook_ireq(x, abort=True), x] 0090 for x in (params.filter or [])] 0091 0092 0093 def process_header (self, hdr, cat): 0094 0095 self.lang=(self.setLang or cat.language()) 0096 if not self.lang: 0097 raise SieveCatalogError( 0098 _("@info", 0099 "Cannot determine language for catalog '%(file)s'.", 0100 file=cat.filename)) 0101 0102 # Force explicitly given accelerators and markup. 0103 if self.setAccel is not None: 0104 cat.set_accelerator(self.setAccel) 0105 if self.setMarkup is not None: 0106 cat.set_markup(self.setMarkup) 0107 0108 0109 def process (self, msg, cat): 0110 0111 if msg.obsolete: 0112 return 0113 0114 try: 0115 for msgstr in msg.msgstr: 0116 0117 # Apply precheck filters. 0118 for pfilter, pfname in self.pfilters: 0119 try: # try as type F1A hook 0120 msgstr = pfilter(msgstr) 0121 except TypeError: 0122 try: # try as type F3* hook 0123 msgstr = pfilter(msgstr, msg, cat) 0124 except TypeError: 0125 raise SieveError( 0126 _("@info", 0127 "Cannot execute filter '%(filt)s'.", 0128 filt=pfname)) 0129 0130 self.connection.request("GET", _REQUEST % (self.lang, urlencode({"text":msgstr.encode("UTF-8")}))) 0131 response=self.connection.getresponse() 0132 if response: 0133 responseData=response.read() 0134 if "error" in responseData: 0135 dom=parseString(responseData) 0136 for error in dom.getElementsByTagName("error"): 0137 if error.getAttribute("ruleId") in self.disabledRules: 0138 continue 0139 self.nmatch+=1 0140 report("-"*(len(msgstr)+8)) 0141 report(_("@info", 0142 "<bold>%(file)s:%(line)d(#%(entry)d)</bold>", 0143 file=cat.filename, line=msg.refline, entry=msg.refentry)) 0144 #TODO: create a report function in the right place 0145 #TODO: color in red part of context that make the mistake 0146 report(_("@info", 0147 "<bold>Context:</bold> %(snippet)s", 0148 snippet=error.getAttribute("context"))) 0149 report(_("@info", 0150 "(%(rule)s) <bold><red>==></red></bold> %(note)s", 0151 rule=error.getAttribute("ruleId"), 0152 note=error.getAttribute("msg"))) 0153 report("") 0154 if self.lokalize: 0155 repls = [_("@label", "Grammar errors:")] 0156 repls.append(_( 0157 "@info", 0158 "<bold>%(file)s:%(line)d(#%(entry)d)</bold>", 0159 file=cat.filename, 0160 line=msg.refline, 0161 entry=msg.refentry 0162 )) 0163 repls.append(_( 0164 "@info", 0165 "(%(rule)s) <bold><red>==></red></bold> %(note)s", 0166 rule=error.getAttribute("ruleId"), 0167 note=error.getAttribute("msg") 0168 )) 0169 report_msg_to_lokalize(msg, cat, cjoin(repls, "\n")) 0170 except socket.error: 0171 raise SieveError(_("@info", 0172 "Cannot connect to LanguageTool server. " 0173 "Did you start it?")) 0174 0175 0176 def finalize (self): 0177 if self.nmatch: 0178 msg = n_("@info:progress", 0179 "Detected %(num)d problem in grammar and style.", 0180 "Detected %(num)d problems in grammar and style.", 0181 num=self.nmatch) 0182 report("===== " + msg) 0183