blob: 9562bb7bb60372e6dd06325b9e0a0cf5eb342467 [file] [log] [blame]
#!/usr/bin/env python3
#
# cace_datasheet_upload.py
#
# Send newly-created challenge datasheet and associated
# design files (testbench schematics and netlists) to
# the marketplace server for storage.
#
import os
import json
import re
import sys
import requests
import subprocess
import file_compressor
import file_request_hash
"""
standalone script.
Makes rest calls to marketplace REST server to save datasheet
and associated file(s). Request hash is generated so the two
requests can be associated on the server side. This action
has no other side effects.
"""
mktp_server_url = ""
# Make request to server sending json passed in.
def send_doc(doc):
result = requests.post(mktp_server_url + '/cace/save_datasheet', json=doc)
print('send_doc', result.status_code)
# Pure HTTP post here. Add the file to files object and the hash/filename
# to the data params.
def send_file(hash, file, file_name):
files = {'file': file.getvalue()}
data = {'request-hash': hash, 'file-name': file_name}
result = requests.post(mktp_server_url + '/cace/save_files', files=files, data=data)
print('send_file', result.status_code)
if __name__ == '__main__':
# Divide up command line into options and arguments
options = []
arguments = []
for item in sys.argv[1:]:
if item.find('-', 0) == 0:
options.append(item)
else:
arguments.append(item)
# There should be two arguments passed to the script. One is
# the path and filename of the datasheet JSON file, and the
# other a path to the location of testbenches (netlists and/or
# schematics). If there is only one argument, then datasheet_filepath
# is assumed to be in the same path as netlist_filepath.
datasheet_filepath = []
netlist_filepath = []
for argval in arguments:
if os.path.isfile(argval):
datasheet_filepath = argval
elif os.path.isdir(argval):
netlist_filepath = argval
elif os.path.splitext(argval)[1] == '':
argname = argval + '.json'
if os.path.isfile(argval):
datasheet_filepath = argname
if not datasheet_filepath:
# Check for JSON file 'project.json' in the netlist filepath directory
# or the directory above it.
if netlist_filepath:
argtry = netlist_filepath + '/project.json'
if os.path.isfile(argtry):
datasheet_filepath = argtry
else:
argtry = os.path.split(netlist_filepath)[0] + '/project.json'
if os.path.isfile(argtry):
datasheet_filepath = argtry
# Legacy behavior support
if not os.path.isfile(datasheet_filepath):
# Check for JSON file with same name as netlist filepath,
# but with a .json extension, in the netlist filepath directory
# or the directory above it.
if netlist_filepath:
argtry = netlist_filepath + '/' + os.path.basename(netlist_filepath) + '.json'
if os.path.isfile(argtry):
datasheet_filepath = argtry
else:
argtry = os.path.split(netlist_filepath)[0] + '/' + os.path.basename(netlist_filepath) + '.json'
if os.path.isfile(argtry):
datasheet_filepath = argtry
if not datasheet_filepath:
print('Error: No datasheet JSON file specified.\n')
sys.exit(1)
if not os.path.isfile(datasheet_filepath):
print('Error: No datasheet JSON file ' + datasheet_filepath + ' found.\n')
sys.exit(1)
# Technically okay to have null netlist_filepath, but unlikely,
# so flag a warning.
if not netlist_filepath:
print('Warning: No netlist filepath given. No files will be '
+ 'transmitted with the datasheet.\n')
dsheet = {}
with open(datasheet_filepath, 'r') as user_doc_file:
docinfo = json.load(user_doc_file)
dsheet = docinfo['data-sheet']
try:
name = dsheet['ip-name']
except KeyError:
datasheet_file = os.path.split(datasheet_filepath)[1]
name = os.path.splitext(datasheet_file)[0]
dsheet['ip-name'] = name
# Behavior starting 4/27/2017: the UID is required to be a
# numeric value, but the datasheet upload is generally being
# done as user admin from the remote CACE host, and admin has
# no official UID number. So always attach ID 9999 to datasheet
# uploads.
if 'UID' in docinfo:
uid = docinfo['UID']
else:
uid = 9999
docinfo['UID'] = uid
# Get a request hash and add it to the JSON document
rhash, timestamp = file_request_hash.get_hash(name)
docinfo['request-hash'] = rhash
# Put the current git system state into the target directory
# prior to tarballing
if os.path.isfile('.version'):
with open('.version', 'r') as f:
ef_version = f.read().rstrip()
docinfo['ef-version'] = ef_version
# Now send the datasheet
if '-test' in options:
print("Test: running send_doc( <docinfo> )\n")
print(" with docinfo['UID'] = " + uid + "\n")
else:
send_doc(docinfo)
# Send the merged JSON file and the tarballed design file directory
# to the marketplace server for storage.
if netlist_filepath:
# Use the version below to ignore the 'spi' directory. However, it may
# be the intention of the challenge creator to seed the challenge with
# an example. This is normally not the case. So use '-include' option
# to avoid excluding the 'spi' folder contents.
if '-includeall' in options:
print('Including netlist/schematic and simulation files in project folder.')
tar = file_compressor.tar_directory_contents(netlist_filepath,
exclude=['elec/\.java', 'elec/electric\.log', name + '\.log',
'.*\.raw', 'ngspice/run/\.allwaves'])
elif '-include' in options:
print('Including netlist/schematic files in project folder.')
tar = file_compressor.tar_directory_contents(netlist_filepath,
exclude=['ngspice', 'elec/\.java', 'elec/electric\.log',
name + '\.log'])
else:
print('Excluding netlist/schematic and simulation files in project folder.')
tar = file_compressor.tar_directory_contents(netlist_filepath,
exclude=['spi', 'ngspice', 'elec/\.java', 'mag', 'elec/electric\.log',
'elec/' + name + '\.delib/' + name + '\.sch', name + '\.log'])
tarballname = name + '.tar.gz'
# Now send the netlist file tarball
if '-test' in options:
print('Test: running send_file(' + rhash + ' <tarball> ' + tarballname + ')')
print('Saving tarball locally as ' + tarballname)
file_compressor.tar_directory_contents_to_file(netlist_filepath,
tarballname, exclude=['spi', 'ngspice', 'elec/\.java', 'mag',
'elec/electric\.log', 'elec/' + name + '\.delib/' + name + '\.sch',
name + '\.log'])
else:
send_file(rhash, tar, tarballname)