#!/usr/bin/env python3
#============================================================================================
# Call oracle2json.py?param (or other Web Services)
# param1 is either sql=SQL_code, or file=file_containing_SQL (web based)
# param2 is also a destination table= to insert the data in
# get the returned data from the Web Service
# insert the returned data into an Oracle database table
# below, identify the database name (actually the db connect string)
#============================================================================================
import sys                                 #to obtain command args
import os.path                             #to check if file exists
import urllib.request                      #urllib.request module allows fetching of urls 
import urllib.parse                        #urllib.parse module allows you to url encode
import cgi                                 #import cgi 
import cgitb                               #import cgi traceback for error handling
cgitb.enable()

sys.path.insert(0,'/home/s/sultans/web/python/demo/etl/util')
import oracle                              #import custom functions for Oracle
import convert                             #import custom functions to convert format
import emailFunc                           #import custom function  to email

db_name = 'demo'                           #identify the db connect string

print("Content-Type: text/html \n")               #required cgi response header(for web only)

param = cgi.FieldStorage()                        #get ONLINE web parameters (if any)
sql   = param.getvalue('sql')   or ''             #get value for web param sql=
file  = param.getvalue('file')  or ''             #get value for web param file=
show  = param.getvalue('show')  or ''             #get value for web param show=
table = param.getvalue('table') or 'temp_table'   #if nothing is entered use 'temp_table'        
msg   = ''
       
url = "https://workshop.sps.nyu.edu/~sultans/python/demo/etl/oracle2json.py"    #Choose the JSON web service
#url = "https://workshop.sps.nyu.edu/~sultans/python/demo/etl/oracle2xml.py"    #Choose the XML web service
#url = "https://workshop.sps.nyu.edu/~sultans/python/demo/etl/oracle2csv.py"    #Choose the CSV web service

#-------------------------------------------------------------------------------------
# Function to validate entry fields 
#-------------------------------------------------------------------------------------
def validate():
    global msg                             
                                                                                
    if not sql and not file:                                
        msg = "Please provide SQL or File name containing SQL"
        return
    if sql and file:                                
        msg = "Please enter either SQL or a file containing SQL, not both"
        return
    if file and not os.path.isfile(file):                #if file is entered, check if exists
        msg = "File does not exist"
        return
 
#-------------------------------------------------------------------------------------
# Function to display the form (must be defined before use)
#-------------------------------------------------------------------------------------
def display():
                                           
    print(F'''
        <!DOCTYPE html>
        <html>
        <head>
        <title>Full HTML entry from</title>
        </head>
        <body bgcolor="lightyellow">
        <h1><center>Call a Web Service</center></h1>
        <form name="form1" method="POST" action=zCallws_web.py>             <!--the name of the current Python script-->
        <fieldset style='width:600px; height:225px; border-color:gold'>
        <legend>Enter Either SQL or a Filename Below</legend>    
        <table bgcolor=lightgray width=600px>
            <tr><td valign=top><b>Source SQL
                <td><textarea name="sql" rows=6 cols=70>{sql}</textarea>
            <tr><td><b>Source Filename
                <td><input type="text" size=68 name="file" value="{file}">
            <tr><td><b>Destination Table
                <td><input type="text" size=68 name="table" value="{table}">
            <tr><td><input type="submit" value="   Submit  ">
                <td><input type="reset"  value="Cancel">
                    <input type="checkbox" name="show" >
                    Show returned data

        </table>
        </fieldset>
        </form>
        <p style='color:red'>{msg}</p>
        </body>
        </html>
    ''')        
        
#-------------------------------------------------------------------------------------
#encode64: encrypt user:pswd to base64
#          this is not needed if your website is not htaccess secured
#-------------------------------------------------------------------------------------
def encode64(input):
    import base64                              #encode base64

    input = input.replace('Basic','')          #remove 'Basic'
    input = input.strip()                      #trim whitespace
    bArray      = input.encode()               #convert the string to byte array
    encoded_arr = base64.b64encode(bArray)     #encode it base64
    encoded_str = encoded_arr.decode()         #convert the byte array back to string
    encoded_str = 'Basic ' + encoded_str       #re-add 'Basic'
    return(encoded_str)

authValue    = 'Basic student:123'
encryptValue = encode64(authValue)             # Basic c3R1ZGVudDoxMjM=

#-------------------------------------------------------------------------------------
# main code
#-------------------------------------------------------------------------------------

if (sql or param):                           #if fields were entered
    validate()                               #validate the input

sql2 = urllib.parse.quote(sql)               #URL encode the SQL
if sql:  url += '?sql='  + sql2              #the full url with ?sql=SQL  
if file: url += '?file=' + file              #the full url with ?file=filename 

if (sql or param) and msg=='':                        #if form fields were entered, and no errors                               
    try:                                              #Call web service
        req  = urllib.request.Request(url)            #create a request object
        req.add_header('Authorization', encryptValue) #add 'Authorization: value' header (optional) 
        resp = urllib.request.urlopen(req)            #send the request
        data = resp.read()                            #read the returned data
        data = data.decode('utf-8')                   #convert it from array of bytes to string 
    except:
        msg = F"<p style='color:red'>Error calling web service</p>{url}" 
        
if (sql or param) and msg=='':                        #if form fields were entered, and no errors                               
    try:                                              #Convert returned data
        if 'json' in url:
            list_dict = convert.json2obj(data)        #convert JSON to Python list of dictionaries
        if 'xml' in url:
            list_dict = convert.xml2obj(data)         #convert XML to Python list of dictionaries
        if 'csv' in url: 
            list_dict = convert.csv2obj(data)         #convert CSV to Python list of dictionaries
    except:
        msg = F"<p style='color:red'>Error converting your returned data</p>{data}" 

if (sql or param) and msg=='':                        #if form fields were entered, and no errors                               
    try:                                                         
        oracle.dropTable(db_name, table)                           #drop table
        oracle.createTable(db_name, table, list_dict)              #create table
        insert_count = oracle.insert(db_name, table, list_dict)    #insert into database    
        msg = F"<h3>{insert_count} rows inserted in table {table}</h3>"
    except:
        msg = F"<p style='color:red'>Error inserting your data in table {table}</p>" 

display()                                            #display the html form

if show:
    data2 = data.replace('\n','<br>')
    print(data2)
    
#============================================================================================