Commits

Kirill Simonov committed 9b41ba1

Changed signature of the `post` shell command.

  • Participants
  • Parent commits f55ead4

Comments (0)

Files changed (3)

File src/htsql/ctl/shell.py

 from .error import ScriptError
 from .request import Request, DBRoutine
 from ..core.util import listof, trim_doc
-from ..core.model import (HomeNode, InvalidNode, InvalidArc, TableArc, 
-                          ColumnArc, ChainArc, AmbiguousArc)
+from ..core.model import (HomeNode, InvalidNode, InvalidArc, TableArc,
+        ColumnArc, ChainArc, AmbiguousArc)
 from ..core.classify import classify, normalize
 import traceback
 import StringIO
 
     @classmethod
     def complete(cls, routine, argument):
+        # FIXME: handle post arguments.
         if routine.state.app is None:
             return
         argument = argument.decode('utf-8', 'replace')
         return names
 
     def execute(self):
-        # Check if the argument of the command looks like an HTSQL query.
+        # Parse the argument.
         if not self.argument:
             self.ctl.out("** a query is expected")
             return
-        if self.argument[0] != '/':
-            self.ctl.out("** a query is expected; got %r" % self.argument)
+
+        query = self.argument
+
+        # Extract a filename and content type for a POST request.
+        if self.method == 'POST':
+            chunks = query.split(None, 1)
+            query = chunks.pop()
+            if not chunks:
+                self.ctl.out("** a file name is expected")
+                return
+            content_path = chunks.pop()
+            content_type = None
+            chunks = query.split(None, 1)
+            if len(chunks) == 2 and chunks[0][0] != '/':
+                query = chunks.pop()
+                content_type = chunks.pop()
+
+        if query[0] != '/':
+            self.ctl.out("** a query is expected; got %r" % query)
             return
 
         # Prepare the WSGI `environ` for a GET request.
 
         # Prepare the WSGI `environ` for a POST request.
         if self.method == 'POST':
-            # Get the name of the file containing POST data of the request.
-            if self.ctl.is_interactive:
-                self.ctl.out("File with POST data:", end=" ")
-            content_path = self.ctl.stdin.readline().strip()
             if not content_path:
                 self.ctl.out("** a file name is expected")
                 return
             content_body = open(content_path, 'rb').read()
 
             # Determine the content type of the POST data.
-            default_content_type = mimetypes.guess_type(content_path)[0]
-            if default_content_type is None:
-                default_content_type = 'application/octet-stream'
-            if self.ctl.is_interactive:
-                self.ctl.out("Content type [%s]:" % default_content_type,
-                             end=" ")
-            content_type = self.ctl.stdin.readline().strip()
             if not content_type:
-                content_type = default_content_type
+                content_type = mimetypes.guess_type(content_path)[0]
+                if content_type is None:
+                    content_type = 'application/octet-stream'
 
             request = Request.prepare('POST', query=self.argument,
                                       remote_user=self.state.remote_user,
     """
 
     name = 'post'
-    signature = """post /query"""
+    signature = """post filename /query"""
     hint = """execute an HTSQL query with POST data"""
     help = """
-    Type `post /query` to execute an HTSQL query with POST data.
+    Type `post filename /query` or `post filename content-type /query` to
+    execute an HTSQL query with POST data.
 
-    You will be asked to provide a file containing the POST data and to
-    indicate the content type of the data.
+    The content of the POST request is read from the file `filename`.  You
+    can optionally specify the content type of the POST data as a second
+    parameter.  If content type is not specified, it is deduced from the
+    file extension.
 
     The output of the query is dumped to the console.  When the pager is
     enabled and the number of lines in the response body exceeds the height
         self.completer_delims = completer_delims
         self.completions = completions
 
+
 class VersionCmd(Cmd):
     """
     Implements the `version` command.

File test/input/routine.yaml

       /count(school)
       /error
   # Post
+  - write: build/regress/post.json
+    data: |
+      { "school_code": "art" }
   - write: build/regress/post.data
     data: "school_code=art"
   - ctl: [shell, *db]
     stdin: |
       help post
       post
-      post /school
-      build/regress/post.data
-      application/x-www-form-urlencoded
-      post /school
-      error
-  - remove: [build/regress/post.data]
+      post build/regress/post.json /school
+      post build/regress/post.data application/x-www-form-urlencoded /school
+      post error /school
+  - remove: [build/regress/post.json, build/regress/post.data]
   # Run
   - write: build/regress/run.htsql
     data: |

File test/output/routine.yaml

         headers on|off           : display HTTP status line and headers
         pager on|off             : pipe long output to a pager
         [get] /query             : execute an HTSQL query
-        post /query              : execute an HTSQL query with POST data
+        post filename /query     : execute an HTSQL query with POST data
         run filename.htsql       : run an HTSQL query from a file
 
       Arguments:
         headers on|off           : display HTTP status line and headers
         pager on|off             : pipe long output to a pager
         [get] /query             : execute an HTSQL query
-        post /query              : execute an HTSQL query with POST data
+        post filename /query     : execute an HTSQL query with POST data
         run filename.htsql       : run an HTSQL query from a file
 
       help error
       license information.
 
       version
-      HTSQL 2.3.2
-      Copyright (c) 2006-2012, Prometheus Research, LLC
+      HTSQL 2.3.3
+      Copyright (c) 2006-2013, Prometheus Research, LLC
 
       This is free software: you are free to change and redistribute it.
       There is NO WARRANTY, to the extent permitted by law.  This software
     stdout: |
       help post
       POST - execute an HTSQL query with POST data
-      Usage: post /query
+      Usage: post filename /query
 
-      Type `post /query` to execute an HTSQL query with POST data.
+      Type `post filename /query` or `post filename content-type /query` to
+      execute an HTSQL query with POST data.
 
-      You will be asked to provide a file containing the POST data and to
-      indicate the content type of the data.
+      The content of the POST request is read from the file `filename`.  You
+      can optionally specify the content type of the POST data as a second
+      parameter.  If content type is not specified, it is deduced from the
+      file extension.
 
       The output of the query is dumped to the console.  When the pager is
       enabled and the number of lines in the response body exceeds the height
 
       post
       ** a query is expected
-      post /school
-      build/regress/post.data
-      application/x-www-form-urlencoded
+      post build/regress/post.json /school
       POST requests are not permitted.
-      post /school
-      error
+      post build/regress/post.data application/x-www-form-urlencoded /school
+      POST requests are not permitted.
+      post error /school
       ** file 'error' does not exist
     exit: 0
   - ctl: [shell, 'sqlite:build/regress/sqlite/htsql_demo.sqlite']