blob: af5db63d8b0d8c3dcee19fcb2939336f3e464fc3 [file] [log] [blame]
Tim Edwardsdae621a2021-09-08 09:28:02 -04001#!/usr/bin/env python3
emayecs5966a532021-07-29 10:07:02 -04002#
3# cace_datasheet_upload.py
4#
5# Send newly-created challenge datasheet and associated
6# design files (testbench schematics and netlists) to
7# the marketplace server for storage.
8#
9
10import os
11import json
12import re
13import sys
14import requests
15import subprocess
16
17import file_compressor
18import file_request_hash
19
emayecsb2487ae2021-08-05 10:30:13 -040020import config
emayecs5966a532021-07-29 10:07:02 -040021
22"""
emayecs14748312021-08-05 14:21:26 -040023 standalone script.
emayecs5966a532021-07-29 10:07:02 -040024 Makes rest calls to marketplace REST server to save datasheet
25 and associated file(s). Request hash is generated so the two
26 requests can be associated on the server side. This action
27 has no other side effects.
28"""
29
emayecsb2487ae2021-08-05 10:30:13 -040030mktp_server_url = config.mktp_server_url
emayecs5966a532021-07-29 10:07:02 -040031
32# Make request to server sending json passed in.
33def send_doc(doc):
34 result = requests.post(mktp_server_url + '/cace/save_datasheet', json=doc)
35 print('send_doc', result.status_code)
36
37# Pure HTTP post here. Add the file to files object and the hash/filename
38# to the data params.
39def send_file(hash, file, file_name):
40 files = {'file': file.getvalue()}
41 data = {'request-hash': hash, 'file-name': file_name}
42 result = requests.post(mktp_server_url + '/cace/save_files', files=files, data=data)
43 print('send_file', result.status_code)
44
45
46if __name__ == '__main__':
47
48 # Divide up command line into options and arguments
49 options = []
50 arguments = []
51 for item in sys.argv[1:]:
52 if item.find('-', 0) == 0:
53 options.append(item)
54 else:
55 arguments.append(item)
56
57 # There should be two arguments passed to the script. One is
58 # the path and filename of the datasheet JSON file, and the
59 # other a path to the location of testbenches (netlists and/or
60 # schematics). If there is only one argument, then datasheet_filepath
61 # is assumed to be in the same path as netlist_filepath.
62
63 datasheet_filepath = []
64 netlist_filepath = []
65
66 for argval in arguments:
67 if os.path.isfile(argval):
68 datasheet_filepath = argval
69 elif os.path.isdir(argval):
70 netlist_filepath = argval
71 elif os.path.splitext(argval)[1] == '':
72 argname = argval + '.json'
73 if os.path.isfile(argval):
74 datasheet_filepath = argname
75
76 if not datasheet_filepath:
77 # Check for JSON file 'project.json' in the netlist filepath directory
78 # or the directory above it.
79 if netlist_filepath:
80 argtry = netlist_filepath + '/project.json'
81 if os.path.isfile(argtry):
82 datasheet_filepath = argtry
83 else:
84 argtry = os.path.split(netlist_filepath)[0] + '/project.json'
85 if os.path.isfile(argtry):
86 datasheet_filepath = argtry
87
88 # Legacy behavior support
89 if not os.path.isfile(datasheet_filepath):
90 # Check for JSON file with same name as netlist filepath,
91 # but with a .json extension, in the netlist filepath directory
92 # or the directory above it.
93 if netlist_filepath:
94 argtry = netlist_filepath + '/' + os.path.basename(netlist_filepath) + '.json'
95 if os.path.isfile(argtry):
96 datasheet_filepath = argtry
97 else:
98 argtry = os.path.split(netlist_filepath)[0] + '/' + os.path.basename(netlist_filepath) + '.json'
99 if os.path.isfile(argtry):
100 datasheet_filepath = argtry
101
102 if not datasheet_filepath:
103 print('Error: No datasheet JSON file specified.\n')
104 sys.exit(1)
105
106 if not os.path.isfile(datasheet_filepath):
107 print('Error: No datasheet JSON file ' + datasheet_filepath + ' found.\n')
108 sys.exit(1)
109
110 # Technically okay to have null netlist_filepath, but unlikely,
111 # so flag a warning.
112
113 if not netlist_filepath:
114 print('Warning: No netlist filepath given. No files will be '
115 + 'transmitted with the datasheet.\n')
116
117 dsheet = {}
118 with open(datasheet_filepath, 'r') as user_doc_file:
119 docinfo = json.load(user_doc_file)
120 dsheet = docinfo['data-sheet']
121 try:
122 name = dsheet['ip-name']
123 except KeyError:
124 datasheet_file = os.path.split(datasheet_filepath)[1]
125 name = os.path.splitext(datasheet_file)[0]
126 dsheet['ip-name'] = name
127
128 # Behavior starting 4/27/2017: the UID is required to be a
129 # numeric value, but the datasheet upload is generally being
130 # done as user admin from the remote CACE host, and admin has
131 # no official UID number. So always attach ID 9999 to datasheet
132 # uploads.
133
134 if 'UID' in docinfo:
135 uid = docinfo['UID']
136 else:
137 uid = 9999
138 docinfo['UID'] = uid
139
140 # Get a request hash and add it to the JSON document
141 rhash, timestamp = file_request_hash.get_hash(name)
142 docinfo['request-hash'] = rhash
143
144 # Put the current git system state into the target directory
145 # prior to tarballing
146 if os.path.isfile('/ef/.ef-version'):
147 with open('/ef/.ef-version', 'r') as f:
148 ef_version = f.read().rstrip()
149 docinfo['ef-version'] = ef_version
150
151 # Now send the datasheet
152 if '-test' in options:
153 print("Test: running send_doc( <docinfo> )\n")
154 print(" with docinfo['UID'] = " + uid + "\n")
155 else:
156 send_doc(docinfo)
157
158 # Send the merged JSON file and the tarballed design file directory
159 # to the marketplace server for storage.
160
161 if netlist_filepath:
162 # Use the version below to ignore the 'spi' directory. However, it may
163 # be the intention of the challenge creator to seed the challenge with
164 # an example. This is normally not the case. So use '-include' option
165 # to avoid excluding the 'spi' folder contents.
166 if '-includeall' in options:
167 print('Including netlist/schematic and simulation files in project folder.')
168 tar = file_compressor.tar_directory_contents(netlist_filepath,
169 exclude=['elec/\.java', 'elec/electric\.log', name + '\.log',
170 '.*\.raw', 'ngspice/run/\.allwaves'])
171 elif '-include' in options:
172 print('Including netlist/schematic files in project folder.')
173 tar = file_compressor.tar_directory_contents(netlist_filepath,
174 exclude=['ngspice', 'elec/\.java', 'elec/electric\.log',
175 name + '\.log'])
176 else:
177 print('Excluding netlist/schematic and simulation files in project folder.')
178 tar = file_compressor.tar_directory_contents(netlist_filepath,
179 exclude=['spi', 'ngspice', 'elec/\.java', 'mag', 'elec/electric\.log',
180 'elec/' + name + '\.delib/' + name + '\.sch', name + '\.log'])
181 tarballname = name + '.tar.gz'
182
183 # Now send the netlist file tarball
184 if '-test' in options:
185 print('Test: running send_file(' + rhash + ' <tarball> ' + tarballname + ')')
186 print('Saving tarball locally as ' + tarballname)
187 file_compressor.tar_directory_contents_to_file(netlist_filepath,
188 tarballname, exclude=['spi', 'ngspice', 'elec/\.java', 'mag',
189 'elec/electric\.log', 'elec/' + name + '\.delib/' + name + '\.sch',
190 name + '\.log'])
191 else:
192 send_file(rhash, tar, tarballname)
193