Prechádzať zdrojové kódy

[slack] Show fetch result, refactor payload function and better UI

Harshg999 4 rokov pred
rodič
commit
0549f3db38

+ 1 - 0
desktop/core/requirements.txt

@@ -40,6 +40,7 @@ mysqlclient==1.4.6
 nose==1.3.7
 nose==1.3.7
 openpyxl==2.6.2
 openpyxl==2.6.2
 phoenixdb==1.0.0
 phoenixdb==1.0.0
+prettytable==2.1.0
 pyformance==0.3.2
 pyformance==0.3.2
 pylint==2.6.0
 pylint==2.6.0
 pylint-django==2.3.0
 pylint-django==2.3.0

+ 77 - 11
desktop/core/src/desktop/lib/botserver/views.py

@@ -25,6 +25,12 @@ from desktop.conf import ENABLE_GIST_PREVIEW
 from desktop.lib.django_util import login_notrequired, JsonResponse
 from desktop.lib.django_util import login_notrequired, JsonResponse
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.lib.exceptions_renderable import PopupException
 from desktop.models import Document2, _get_gist_document
 from desktop.models import Document2, _get_gist_document
+from desktop.auth.backend import rewrite_user
+
+from notebook.api import _fetch_result_data, _check_status, _execute_notebook
+from notebook.models import MockRequest
+
+from useradmin.models import User
 
 
 from django.http import HttpResponse
 from django.http import HttpResponse
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
@@ -32,6 +38,11 @@ from django.views.decorators.csrf import csrf_exempt
 
 
 LOG = logging.getLogger(__name__)
 LOG = logging.getLogger(__name__)
 
 
+try:
+  from prettytable import PrettyTable
+except ImportError:
+  raise ImportError("prettytable module not found")
+
 SLACK_VERIFICATION_TOKEN = conf.SLACK.SLACK_VERIFICATION_TOKEN.get()
 SLACK_VERIFICATION_TOKEN = conf.SLACK.SLACK_VERIFICATION_TOKEN.get()
 SLACK_BOT_USER_TOKEN = conf.SLACK.SLACK_BOT_USER_TOKEN.get()
 SLACK_BOT_USER_TOKEN = conf.SLACK.SLACK_BOT_USER_TOKEN.get()
 
 
@@ -89,6 +100,7 @@ def handle_on_message(channel_id, bot_id, text, user_id):
       if not response['ok']:
       if not response['ok']:
         raise PopupException(_("Error posting message"), detail=response["error"])
         raise PopupException(_("Error posting message"), detail=response["error"])
 
 
+
 def handle_on_link_shared(channel_id, message_ts, links):
 def handle_on_link_shared(channel_id, message_ts, links):
   for item in links:
   for item in links:
     path = urlsplit(item['url'])[2]
     path = urlsplit(item['url'])[2]
@@ -97,25 +109,67 @@ def handle_on_link_shared(channel_id, message_ts, links):
     try:
     try:
       if path == '/hue/editor' and id_type == 'editor':
       if path == '/hue/editor' and id_type == 'editor':
         doc = Document2.objects.get(id=qid)
         doc = Document2.objects.get(id=qid)
+        doc_type = 'Editor'
       elif path == '/hue/gist' and id_type == 'uuid' and ENABLE_GIST_PREVIEW.get():
       elif path == '/hue/gist' and id_type == 'uuid' and ENABLE_GIST_PREVIEW.get():
         doc = _get_gist_document(uuid=qid)
         doc = _get_gist_document(uuid=qid)
+        doc_type = 'Gist'
       else:
       else:
         raise PopupException(_("Cannot unfurl link"))
         raise PopupException(_("Cannot unfurl link"))
     except Document2.DoesNotExist:
     except Document2.DoesNotExist:
       msg = "Document with {key}={value} does not exist".format(key='uuid' if id_type == 'uuid' else 'id', value=qid)
       msg = "Document with {key}={value} does not exist".format(key='uuid' if id_type == 'uuid' else 'id', value=qid)
       raise PopupException(_(msg))
       raise PopupException(_(msg))
 
 
-    doc_data = json.loads(doc.data)
-    statement = doc_data['snippets'][0]['statement_raw'] if id_type == 'editor' else doc_data['statement_raw']
-    dialect = doc_data['dialect'].capitalize() if id_type == 'editor' else doc.extra.capitalize()
-    created_by = doc.owner.get_full_name() or doc.owner.username
-    
-    payload = _make_unfurl_payload(item['url'], statement, dialect, created_by)
+    payload = _make_unfurl_payload(item['url'], id_type, doc, doc_type)
     response = slack_client.chat_unfurl(channel=channel_id, ts=message_ts, unfurls=payload)
     response = slack_client.chat_unfurl(channel=channel_id, ts=message_ts, unfurls=payload)
     if not response['ok']:
     if not response['ok']:
       raise PopupException(_("Cannot unfurl link"), detail=response["error"])
       raise PopupException(_("Cannot unfurl link"), detail=response["error"])
 
 
-def _make_unfurl_payload(url, statement, dialect, created_by):
+
+def query_result(request, notebook):
+  snippet = notebook['snippets'][0]
+  snippet['statement'] = notebook['snippets'][0]['statement_raw']
+
+  query_execute = _execute_notebook(request, notebook, snippet)
+
+  history_uuid = query_execute['history_uuid']
+  status = _check_status(request, operation_id=history_uuid)
+  if status['query_status']['status'] == 'available':
+    response = _fetch_result_data(request, operation_id=history_uuid)
+
+  return response['result']
+
+
+def _make_result_table(result):
+  meta = []
+  for field in result['meta']:
+    meta.append(field['name'])
+
+  table = PrettyTable()
+  table.field_names = meta
+  table.add_rows(result['data'])
+  return table
+
+
+def _make_unfurl_payload(url, id_type, doc, doc_type):
+  doc_data = json.loads(doc.data)
+  statement = doc_data['snippets'][0]['statement_raw'] if id_type == 'editor' else doc_data['statement_raw']
+  dialect = doc_data['dialect'] if id_type == 'editor' else doc.extra
+  created_by = doc.owner.get_full_name() or doc.owner.username
+
+  # Mock request for query execution and fetch result
+  user = rewrite_user(User.objects.get(username=doc.owner.username))
+  request = MockRequest(user=user)
+
+  if id_type == 'editor':
+    try:
+      status = _check_status(request, operation_id=doc_data['uuid'])
+      if status['query_status']['status'] == 'available':
+        result = _make_result_table(query_result(request, json.loads(doc.data)))
+    except:
+      result = 'Query result has expired or could not be found.'
+  else:
+    result = 'Result is not available for Gist.'
+
   payload = {
   payload = {
     url: {
     url: {
       "color": "#025BA6",
       "color": "#025BA6",
@@ -124,14 +178,17 @@ def _make_unfurl_payload(url, statement, dialect, created_by):
           "type": "section",
           "type": "section",
           "text": {
           "text": {
             "type": "mrkdwn",
             "type": "mrkdwn",
-            "text": "\n*<{}|Hue - SQL Editor>*".format(url)
+            "text": "\n*<{}|Hue - SQL {}>*".format(url, doc_type)
           }
           }
         },
         },
+        {
+          "type": "divider"
+				},
         {
         {
           "type": "section",
           "type": "section",
           "text": {
           "text": {
             "type": "mrkdwn",
             "type": "mrkdwn",
-            "text": statement if len(statement) < 150 else (statement[:150] + '...')
+            "text": "*Statement:*\n```{}```".format(statement if len(statement) < 150 else (statement[:150] + '...'))
           }
           }
         },
         },
         {
         {
@@ -143,15 +200,24 @@ def _make_unfurl_payload(url, statement, dialect, created_by):
             },
             },
             {
             {
               "type": "mrkdwn",
               "type": "mrkdwn",
-              "text": "*Created By:*\n{}".format(created_by)
+              "text": "*Created by:*\n{}".format(created_by)
             }
             }
           ]
           ]
-        }
+        },
+        {
+          "type": "section",
+          "text": {
+            "type": "mrkdwn",
+            "text": "*Query result:*\n```{}```".format(result),
+          }
+				}
       ]
       ]
     }
     }
   }
   }
+
   return payload
   return payload
 
 
+
 def say_hi_user(channel_id, user_id):
 def say_hi_user(channel_id, user_id):
   """
   """
   Sends Hi<user_id> message in a specific channel.
   Sends Hi<user_id> message in a specific channel.