Grammalecte  Diff

Differences From Artifact [4958939df5]:

To Artifact [ebda6f5998]:


     1      1    #!/usr/bin/env python3
            2  +
            3  +"""
            4  +Grammalecte server: grammar checker
            5  +"""
     2      6   
     3      7   import sys
     4      8   import argparse
     5      9   import json
     6     10   import traceback
     7     11   import time
     8     12   
     9         -from grammalecte.bottle import Bottle, run, request, response, template, static_file
           13  +from grammalecte.bottle import Bottle, run, request, response #, template, static_file
    10     14   
    11     15   import grammalecte
    12     16   import grammalecte.text as txt
    13     17   from grammalecte.graphspell.echo import echo
    14     18   
    15     19   
    16     20   HOMEPAGE = """
................................................................................
    83     87   """
    84     88   
    85     89   
    86     90   TESTPAGE = False
    87     91   
    88     92   
    89     93   def genUserId ():
           94  +    "generator: returns id as string for users"
    90     95       i = 0
    91     96       while True:
    92     97           yield str(i)
    93     98           i += 1
    94     99   
    95    100   
    96    101   app = Bottle()
    97    102   
    98    103   # GET
    99    104   @app.route("/")
   100    105   def mainPage ():
          106  +    "page for testing purpose"
   101    107       if TESTPAGE:
   102    108           return HOMEPAGE
   103    109           #return template("main", {})
   104    110       return SADLIFEOFAMACHINE
   105    111   
   106    112   @app.route("/get_options/fr")
   107    113   def listOptions ():
          114  +    "returns grammar options in a text JSON format"
   108    115       sUserId = request.cookies.user_id
   109    116       dOptions = dUser[sUserId]["gc_options"]  if sUserId and sUserId in dUser  else dGCOptions
   110    117       return '{ "values": ' + json.dumps(dOptions) + ', "labels": ' + json.dumps(gce.getOptionsLabels("fr"), ensure_ascii=False) + ' }'
   111    118   
   112    119   
   113    120   # POST
   114    121   @app.route("/gc_text/fr", method="POST")
   115    122   def gcText ():
          123  +    "parse text and returns errors in a JSON text format"
   116    124       #if len(lang) != 2 or lang != "fr":
   117    125       #    abort(404, "No grammar checker available for lang “" + str(lang) + "”")
   118    126       bComma = False
   119    127       dOptions = None
   120    128       sError = ""
   121    129       if request.cookies.user_id:
   122    130           if request.cookies.user_id in dUser:
................................................................................
   124    132               response.set_cookie("user_id", request.cookies.user_id, path="/", max_age=86400) # we renew cookie for 24h
   125    133           else:
   126    134               response.delete_cookie("user_id", path="/")
   127    135       if request.forms.options:
   128    136           try:
   129    137               dOptions = dict(dGCOptions)  if not dOptions  else dict(dOptions)
   130    138               dOptions.update(json.loads(request.forms.options))
   131         -        except:
          139  +        except (TypeError, json.JSONDecodeError):
   132    140               sError = "request options not used"
   133    141       sJSON = '{ "program": "grammalecte-fr", "version": "'+gce.version+'", "lang": "'+gce.lang+'", "error": "'+sError+'", "data" : [\n'
   134    142       for i, sText in enumerate(txt.getParagraph(request.forms.text), 1):
   135    143           if bool(request.forms.tf):
   136    144               sText = oTextFormatter.formatText(sText)
   137    145           sText = oGrammarChecker.generateParagraphAsJSON(i, sText, dOptions=dOptions, bEmptyIfNoErrors=True, bReturnText=bool(request.forms.tf))
   138    146           if sText:
................................................................................
   141    149               sJSON += sText
   142    150               bComma = True
   143    151       sJSON += "\n]}\n"
   144    152       return sJSON
   145    153   
   146    154   @app.route("/set_options/fr", method="POST")
   147    155   def setOptions ():
          156  +    "set grammar options for current user"
   148    157       if request.forms.options:
   149    158           sUserId = request.cookies.user_id  if request.cookies.user_id  else next(userGenerator)
   150    159           dOptions = dUser[sUserId]["gc_options"]  if sUserId in dUser  else dict(dGCOptions)
   151    160           try:
   152    161               dOptions.update(json.loads(request.forms.options))
   153    162               dUser[sUserId] = { "time": int(time.time()), "gc_options": dOptions }
   154    163               response.set_cookie("user_id", sUserId, path="/", max_age=86400) # 24h
   155    164               return json.dumps(dUser[sUserId]["gc_options"])
   156         -        except:
          165  +        except (KeyError, json.JSONDecodeError):
   157    166               traceback.print_exc()
   158    167               return '{"error": "options not registered"}'
   159    168       return '{"error": "no options received"}'
   160    169   
   161    170   @app.route("/reset_options/fr", method="POST")
   162    171   def resetOptions ():
          172  +    "default grammar options"
   163    173       if request.cookies.user_id and request.cookies.user_id in dUser:
   164    174           del dUser[request.cookies.user_id]
   165    175       return "done"
   166    176   
   167    177   @app.route("/format_text/fr", method="POST")
   168    178   def formatText ():
          179  +    "apply the text formatter and returns text"
   169    180       return oTextFormatter.formatText(request.forms.text)
   170    181   
   171    182   #@app.route('/static/<filepath:path>')
   172    183   #def server_static (filepath):
   173    184   #    return static_file(filepath, root='./views/static')
   174    185   
   175    186   
................................................................................
   177    188       "delete user options older than n hours"
   178    189       try:
   179    190           nNowMinusNHours = int(time.time()) - (int(request.forms.hours) * 60 * 60)
   180    191           for nUserId, dValue in dUser.items():
   181    192               if dValue["time"] < nNowMinusNHours:
   182    193                   del dUser[nUserId]
   183    194           return True
   184         -    except:
          195  +    except KeyError:
   185    196           traceback.print_exc()
   186    197           return False
   187    198   
   188    199   
   189    200   # ERROR
   190    201   @app.error(404)
   191    202   def error404 (error):
          203  +    "404 error page"
   192    204       return 'Error 404.<br/>' + str(error)
   193    205   
   194    206   
   195    207   # initialisation
   196    208   oGrammarChecker = grammalecte.GrammarChecker("fr", "Server")
   197    209   oSpellChecker = oGrammarChecker.getSpellChecker()
   198    210   oLexicographer = oGrammarChecker.getLexicographer()
................................................................................
   201    213   
   202    214   dGCOptions = gce.getOptions()
   203    215   dUser = {}
   204    216   userGenerator = genUserId()
   205    217   
   206    218   
   207    219   def main (sHost="localhost", nPort=8080, dOptions=None, bTestPage=False):
   208         -    # start server
          220  +    "start server"
   209    221       global dGCOptions
   210    222       global TESTPAGE
   211    223       global HOMEPAGE
   212    224   
   213    225       if bTestPage:
   214    226           TESTPAGE = True
   215    227           HOMEPAGE = HOMEPAGE.replace("{SERVER_PORT}", str(nPort))
................................................................................
   237    249       if xArgs.opt_on  or  xArgs.opt_off:
   238    250           dOpt = {}
   239    251           if xArgs.opt_on:
   240    252               dOpt = { opt:True  for opt in xArgs.opt_on }
   241    253           if xArgs.opt_off:
   242    254               dOpt.update({ opt:False  for opt in xArgs.opt_off })
   243    255   
   244         -    sHost = xArgs.host  or  "localhost"
   245         -    nPort = xArgs.port  or  8080
   246         -    main(sHost, nPort, dOpt, xArgs.test_page)
          256  +    main(xArgs.host or "localhost", \
          257  +         xArgs.port or 8080, \
          258  +         dOpt,
          259  +         xArgs.test_page)