@ -23,7 +23,8 @@
import json
import json
import logging
import logging
from odoo import http
from odoo import http
from odoo . http import request
from odoo . http import request , Response
from ast import literal_eval
_logger = logging . getLogger ( __name__ )
_logger = logging . getLogger ( __name__ )
@ -38,80 +39,83 @@ class RestApi(http.Controller):
user_id = request . env [ ' res.users ' ] . search ( [ ( ' api_key ' , ' = ' , api_key ) ] )
user_id = request . env [ ' res.users ' ] . search ( [ ( ' api_key ' , ' = ' , api_key ) ] )
if api_key is not None and user_id :
if api_key is not None and user_id :
response = True
return True
elif not user_id :
elif not user_id :
response = ( ' <html><body><h2>Invalid <i>API Key</i> '
return Response ( json . dumps ( { ' message ' : ' Invalid API Key ' } ) , status = 401 )
' !</h2></body></html> ' )
return Response ( json . dumps ( { ' message ' : ' No API Key Provided ' } ) , status = 400 )
else :
response = ( " <html><body><h2>No <i>API Key</i> Provided "
" !</h2></body></html> " )
return response
def simplest_type ( self , input ) :
""" Try cast input into native Python class, otherwise return as string """
try :
return literal_eval ( input )
except :
if input == ' true ' :
return True
if input == ' false ' :
return False
return input
def generate_response ( self , method , model , rec_id ) :
def generate_response ( self , method , * * query ) :
""" This function is used to generate the response based on the type
""" This function is used to generate the response based on the type
of request and the parameters given """
of request and the parameters given """
model = query . pop ( ' model ' )
option = request . env [ ' connection.api ' ] . search (
option = request . env [ ' connection.api ' ] . search (
[ ( ' model_id ' , ' = ' , model ) ] , limit = 1 )
[ ( ' model_id ' , ' = ' , model ) ] , limit = 1 )
model_name = option . model_id . model
model_name = option . model_id . model
model_display_name = option . model_id . name
if method != ' DELETE ' :
data = json . loads ( request . httprequest . data )
else :
data = { }
data = { }
try :
data = json . loads ( request . httprequest . data )
except :
pass
fields = [ ]
fields = [ ]
if data :
if data :
for field in data [ ' fields ' ] :
for field in data [ ' fields ' ] :
fields . append ( field )
fields . append ( field )
if not fields and method != ' DELETE ' :
if ' * ' in fields :
return ( " <html><body><h2>No fields selected for the model "
fields = [ ]
" </h2></body></html> " )
record_fields = request . env [
str ( model_name ) ] . fields_get ( [ ] , attributes = [ ' type ' ] )
for field , value in record_fields . items ( ) :
value_type = value . get ( ' type ' )
if not ( value_type == ' binary ' or value_type == ' datetime ' ) :
fields . append ( field )
if not option :
if not option :
return ( " <html><body><h2>No Record Created for the model "
return Response ( json . dumps ( { ' message ' : f ' No Record Created for the model. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) , status = 403 )
" </h2></body></html> " )
try :
try :
if method == ' GET ' :
if method == ' GET ' :
fields = [ ]
if not fields :
for field in data [ ' fields ' ] :
fields . append ( ' id ' )
fields . append ( field )
if not option . is_get :
if not option . is_get :
return ( " <html><body><h2>Method Not Allowed "
return Response (
" </h2></body></html> " )
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
status = 405 )
else :
else :
datas = [ ]
domains = [ ]
if rec_id != 0 :
for key , value in query . items ( ) :
domains . append ( ( key , ' = ' , self . simplest_type ( value ) ) )
partner_records = request . env [
partner_records = request . env [
str ( model_name ) ] . search_read (
str ( model_name ) ] . search_read (
domain = [ ( ' id ' , ' = ' , rec_id ) ] ,
domain = domains ,
fields = fields
fields = fields
)
)
data = json . dumps ( {
return Response (
json . dumps ( {
' records ' : partner_records
' records ' : partner_records
} )
} )
datas . append ( data )
return request . make_response ( data = datas )
else :
partner_records = request . env [
str ( model_name ) ] . search_read (
domain = [ ] ,
fields = fields
)
)
data = json . dumps ( {
' records ' : partner_records
} )
datas . append ( data )
return request . make_response ( data = datas )
except :
return ( " <html><body><h2>Invalid JSON Data "
" </h2></body></html> " )
if method == ' POST ' :
if method == ' POST ' :
if not option . is_post :
if not option . is_post :
return ( " <html><body><h2>Method Not Allowed "
return Response (
" </h2></body></html> " )
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
else :
status = 405 )
if not data or ' values ' not in data :
return Response ( json . dumps ( { ' message ' : ' No Data Provided ' } ) , status = 403 )
try :
try :
data = json . loads ( request . httprequest . data )
data = json . loads ( request . httprequest . data )
datas = [ ]
new_resource = request . env [ str ( model_name ) ] . create (
new_resource = request . env [ str ( model_name ) ] . create (
data [ ' values ' ] )
data [ ' values ' ] )
partner_records = request . env [
partner_records = request . env [
@ -119,29 +123,26 @@ class RestApi(http.Controller):
domain = [ ( ' id ' , ' = ' , new_resource . id ) ] ,
domain = [ ( ' id ' , ' = ' , new_resource . id ) ] ,
fields = fields
fields = fields
)
)
new_data = json . dumps ( { ' New resource ' : partner_records , } )
return Response ( json . dumps ( { ' new_record ' : partner_records } ) , status = 201 )
datas . append ( new_data )
return request . make_response ( data = datas )
except :
except :
return ( " <html><body><h2>Invalid JSON Data "
return Response ( json . dumps ( { ' message ' : ' Invalid JSON Data ' } ) , status = 403 )
" </h2></body></html> " )
if method == ' PUT ' :
if method == ' PUT ' :
if not option . is_put :
if not option . is_put :
return ( " <html><body><h2>Method Not Allowed "
return Response (
" </h2></body></html> " )
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
else :
status = 405 )
if rec_id == 0 :
return ( " <html><body><h2>No ID Provided "
if not ' id ' in query :
" </h2></body></html> " )
return Response ( json . dumps ( { ' message ' : ' No ID Provided ' } ) , status = 403 )
else :
if not data or ' values ' not in data :
return Response ( json . dumps ( { ' message ' : ' No Data Provided ' } ) , status = 403 )
resource = request . env [ str ( model_name ) ] . browse (
resource = request . env [ str ( model_name ) ] . browse (
int ( rec_id ) )
int ( query . get ( ' id ' ) ) )
if not resource . exists ( ) :
if not resource . exists ( ) :
return ( " <html><body><h2>Resource not found "
return Response ( json . dumps ( { ' message ' : ' Resource not found ' } ) , status = 404 )
" </h2></body></html> " )
else :
try :
try :
datas = [ ]
data = json . loads ( request . httprequest . data )
data = json . loads ( request . httprequest . data )
resource . write ( data [ ' values ' ] )
resource . write ( data [ ' values ' ] )
partner_records = request . env [
partner_records = request . env [
@ -149,41 +150,34 @@ class RestApi(http.Controller):
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
fields = fields
fields = fields
)
)
new_data = json . dumps (
return Response ( json . dumps ( { ' updated_record ' : partner_records } ) )
{ ' Updated resource ' : partner_records ,
} )
datas . append ( new_data )
return request . make_response ( data = datas )
except :
except :
return ( " <html><body><h2>Invalid JSON Data "
return Response ( json . dumps ( { ' message ' : ' Invalid JSON value(s) passed ' } ) , status = 403 )
" !</h2></body></html> " )
if method == ' DELETE ' :
if method == ' DELETE ' :
if not option . is_delete :
if not option . is_delete :
return ( " <html><body><h2>Method Not Allowed "
return Response (
" </h2></body></html> " )
json . dumps ( { ' message ' : f ' Method not allowed. Please contact your admininstrator to enable { method } method for { model_display_name } record. ' } ) ,
else :
status = 405 )
if rec_id == 0 :
return ( " <html><body><h2>No ID Provided "
if not ' id ' in query :
" </h2></body></html> " )
return Response ( json . dumps ( { ' message ' : ' No ID Provided ' } ) , status = 403 )
else :
resource = request . env [ str ( model_name ) ] . browse (
resource = request . env [ str ( model_name ) ] . browse (
int ( rec_id ) )
int ( query . get ( ' id ' ) ) )
if not resource . exists ( ) :
if not resource . exists ( ) :
return ( " <html><body><h2>Resource not found "
return Response ( json . dumps ( { ' message ' : ' Resource not found ' } ) , status = 404 )
" </h2></body></html> " )
else :
else :
records = request . env [
records = request . env [
str ( model_name ) ] . search_read (
str ( model_name ) ] . search_read (
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
domain = [ ( ' id ' , ' = ' , resource . id ) ] ,
fields = [ ' id ' , ' display_name ' ]
fields = fields
)
)
remove = json . dumps (
{ " Resource deleted " : records ,
} )
resource . unlink ( )
resource . unlink ( )
return request . make_response ( data = remove )
return Response ( json . dumps ( { ' message ' : ' Resource deleted ' , ' data ' : records } ) , status = 202 )
except :
return Response ( json . dumps ( { ' message ' : ' Internal Server Error ' } ) , status = 500 )
@http . route ( [ ' /send_request ' ] , type = ' http ' ,
@http . route ( [ ' /send_request ' ] , type = ' http ' ,
auth = ' none ' ,
auth = ' none ' ,
@ -196,7 +190,7 @@ class RestApi(http.Controller):
http_method = request . httprequest . method
http_method = request . httprequest . method
api_key = request . httprequest . headers . get ( ' api-key ' )
api_key = request . httprequest . headers . get ( ' api-key ' )
auth_api = self . auth_api_key ( api_key )
auth_api = self . auth_api_key ( api_key )
model = kw . get ( ' model ' )
model = kw . pop ( ' model ' )
username = request . httprequest . headers . get ( ' login ' )
username = request . httprequest . headers . get ( ' login ' )
password = request . httprequest . headers . get ( ' password ' )
password = request . httprequest . headers . get ( ' password ' )
request . session . authenticate ( request . session . db , username ,
request . session . authenticate ( request . session . db , username ,
@ -204,17 +198,12 @@ class RestApi(http.Controller):
model_id = request . env [ ' ir.model ' ] . search (
model_id = request . env [ ' ir.model ' ] . search (
[ ( ' model ' , ' = ' , model ) ] )
[ ( ' model ' , ' = ' , model ) ] )
if not model_id :
if not model_id :
return ( " <html><body><h3>Invalid model, check spelling or maybe "
return Response ( json . dumps (
" the related "
{ ' message ' : ' Invalid model, check spelling or maybe the related module is not installed ' } ) ,
" module is not installed "
status = 403 )
" </h3></body></html> " )
if auth_api == True :
if auth_api == True :
if not kw . get ( ' Id ' ) :
result = self . generate_response ( http_method , model = model_id . id , * * kw )
rec_id = 0
else :
rec_id = int ( kw . get ( ' Id ' ) )
result = self . generate_response ( http_method , model_id . id , rec_id )
return result
return result
else :
else :
return auth_api
return auth_api
@ -239,5 +228,4 @@ class RestApi(http.Controller):
" api-key " : api_key } )
" api-key " : api_key } )
return request . make_response ( data = datas )
return request . make_response ( data = datas )
except :
except :
return ( " <html><body><h2>wrong login credentials "
return Response ( json . dumps ( { ' message ' : ' wrong login credentials ' } ) , status = 401 )
" </h2></body></html> " )