Skip to content

Commit 850bc22

Browse files
CYLCYL
authored andcommitted
Merge branch 'extract_license_data' into develop
2 parents 9f63c04 + b299d41 commit 850bc22

File tree

1 file changed

+152
-9
lines changed

1 file changed

+152
-9
lines changed

about_code_tool/genabout.py

Lines changed: 152 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@
2626
from os.path import exists, dirname, join, abspath, isdir
2727
import about
2828
import csv
29+
import copy
2930
import errno
31+
import json
3032
import getopt
3133
import os
3234
import shutil
3335
import sys
36+
import urllib
37+
import urllib2
38+
3439

3540
__version__ = '0.9.0'
3641

@@ -43,6 +48,33 @@
4348
self_path = abspath(dirname(__file__))
4449

4550

51+
def request_license_data(url, username, api_key, license_key):
52+
"""
53+
Send a request to a given API URL to gather license data.
54+
Authentication through an Api Key and a username.
55+
Returns a python dictionary of results returned by the API.
56+
"""
57+
payload = {
58+
'username': username,
59+
'api_key': api_key,
60+
'format': 'json'
61+
}
62+
63+
full_url = '{0}{1}/?{2}'.format(
64+
url if url.endswith('/') else url + '/',
65+
license_key, urllib.urlencode(payload))
66+
67+
request = urllib2.Request(full_url)
68+
try:
69+
response = urllib2.urlopen(request)
70+
response_content = response.read()
71+
data = json.loads(response_content)
72+
except (urllib2.HTTPError, ValueError):
73+
return {}
74+
else:
75+
return data
76+
77+
4678
class GenAbout(object):
4779
def __init__(self):
4880
self.warnings = []
@@ -162,7 +194,7 @@ def verify_license_files(self, input_list, project_path):
162194

163195
def copy_license_files(self, gen_location, license_list):
164196
"""
165-
copy the 'license_text_file' into the gen_location
197+
Copy the 'license_text_file' into the gen_location
166198
"""
167199
for items in license_list:
168200
license_path = items[0]
@@ -174,19 +206,72 @@ def copy_license_files(self, gen_location, license_list):
174206
makedirs(license_parent_dir)
175207
shutil.copy2(license_path, output_license_path)
176208

177-
#def extract_license_from_url(self):
178-
# # This function needs discussion
179-
# test = urllib2.urlopen("https://enterprise.dejacode.com/license_library/Demo/gpl-1.0/#license-text")
180-
# with open('testdata/test_file.txt', 'wb') as output_file:
181-
# output_file.write(test.read())
209+
def get_dje_license_key(self, input_list):
210+
"""
211+
Get the DJE License Keys
212+
"""
213+
output_list = []
214+
for component in input_list:
215+
for line in component:
216+
try:
217+
if line['dje_license_key']:
218+
dje_license_key_list = []
219+
dje_key = line['dje_license_key']
220+
file_location = line['about_file']
221+
if file_location.endswith('/'):
222+
file_location = file_location.rpartition('/')[0]
223+
about_parent_dir = os.path.dirname(file_location)
224+
dje_license_key_list.append(about_parent_dir)
225+
dje_license_key_list.append(dje_key)
226+
output_list.append(dje_license_key_list)
227+
else:
228+
self.warnings.append(Warn('dje_license_key', '',
229+
"No 'dje_license_key' for " + line['about_file']))
230+
except Exception as e:
231+
print(repr(e))
232+
print("The input does not have the 'dje_license_key' key which is required.")
233+
sys.exit(errno.EINVAL)
234+
return output_list
235+
236+
def extract_dje_license(self, project_path, license_list, url, username, key):
237+
"""
238+
Extract license text from DJE
239+
"""
240+
for items in license_list:
241+
gen_path = items[0]
242+
license_key = items[1]
243+
if '/' in gen_path:
244+
gen_path = gen_path.partition('/')[2]
245+
gen_license_path = join(project_path, gen_path, license_key) + '.LICENSE'
246+
context = self.get_license_text_from_api(url, username, key, license_key)
247+
if not context:
248+
self.errors.append(Error('dje_license_key', license_key,
249+
"Invalid 'dje_license_key'"))
250+
else:
251+
with open(gen_license_path, 'wb') as output:
252+
output.write(context)
253+
254+
@staticmethod
255+
def get_license_text_from_api(url, username, api_key, license_key):
256+
"""
257+
Returns the license_text of a given license_key using an API request.
258+
Returns an empty string if the text is not available.
259+
"""
260+
data = request_license_data(url, username, api_key, license_key)
261+
license_text = data.get('full_text', '')
262+
return license_text
182263

183264
def pre_generation(self, gen_location, input_list, action_num, all_in_one):
184265
"""
185266
check the existence of the output location and handle differently
186267
according to the action_num.
187268
"""
188269
output_list = []
189-
for component in input_list:
270+
# The input_list needs to be copied and be used below.
271+
# Otherwise, the value in the input_list may be changed based on the
272+
# action number below
273+
copied_list = copy.deepcopy(input_list)
274+
for component in copied_list:
190275
for line in component:
191276
component_list = []
192277
file_location = line['about_file']
@@ -357,6 +442,15 @@ def option_usage():
357442
<path>
358443
Project path
359444
--mapping Activate the MAPPING.CONFIG
445+
--extract_license <3 args required> Extract License text and create <license_key>.LICENSE
446+
side-by-side with the .ABOUT from DJE License Library
447+
<--api_url='URL'> - URL to the DJE License Library
448+
<--api_username='user_api'> - The regular DJE username
449+
<--api_key='user_api_key'> - Hash attached to your username which is used
450+
to Authenticate yourself in the API. Contact
451+
us to get the hash key.
452+
Example syntax:
453+
genabout.py --extract_license --api_url='https://enterprise.dejacode.com/api/v1/license_text/' --api_username='<user_api>' --api_key='<user_api_key>'
360454
""")
361455

362456

@@ -366,6 +460,10 @@ def main(args, opts):
366460
all_in_one = False
367461
project_path = ''
368462
mapping_config = False
463+
gen_license = False
464+
api_url = ''
465+
api_username = ''
466+
api_key = ''
369467

370468
for opt, opt_arg in opts:
371469
invalid_opt = True
@@ -426,9 +524,41 @@ def main(args, opts):
426524
else:
427525
mapping_config = True
428526

527+
if opt in ('--extract_license'):
528+
invalid_opt = False
529+
gen_license = True
530+
531+
532+
if opt in ('--api_url'):
533+
invalid_opt = False
534+
if not opt_arg or not 'http' in opt_arg.lower():
535+
print("Invalid option argument.")
536+
option_usage()
537+
sys.exit(errno.EINVAL)
538+
else:
539+
api_url = opt_arg
540+
541+
if opt in ('--api_username'):
542+
invalid_opt = False
543+
if not opt_arg or '/' in opt_arg or '\\' in opt_arg:
544+
print("Invalid option argument.")
545+
option_usage()
546+
sys.exit(errno.EINVAL)
547+
else:
548+
api_username = opt_arg
549+
550+
if opt in ('--api_key'):
551+
invalid_opt = False
552+
if not opt_arg or '/' in opt_arg or '\\' in opt_arg:
553+
print("Invalid option argument.")
554+
option_usage()
555+
sys.exit(errno.EINVAL)
556+
else:
557+
api_key = opt_arg
558+
429559
if invalid_opt:
430560
assert False, 'Unsupported option.'
431-
561+
432562
if not len(args) == 2:
433563
print('Input file and generated location parameters are mandatory.')
434564
syntax()
@@ -460,10 +590,23 @@ def main(args, opts):
460590
components_list = gen.pre_generation(gen_location, input_list, opt_arg_num, all_in_one)
461591
formatted_output = gen.format_output(components_list)
462592
gen.write_output(formatted_output)
593+
594+
# Check do we have all the required arguments: api_url, api_username, api_key
595+
if gen_license:
596+
if not api_url or not api_username or not api_key:
597+
print("Missing argument for --extract_license")
598+
option_usage()
599+
sys.exit(errno.EINVAL)
600+
else:
601+
dje_license_list = gen.get_dje_license_key(input_list)
602+
gen.extract_dje_license(gen_location, dje_license_list, api_url, api_username, api_key)
603+
604+
463605
gen.warnings_errors_summary(gen_location, verb_arg_num)
464606

465607
if __name__ == "__main__":
466-
longopts = ['help', 'version', 'action=', 'verbosity=', 'all-in-one=', 'copy_license=', 'mapping']
608+
longopts = ['help', 'version', 'action=', 'verbosity=', 'all-in-one=', 'copy_license=', 'mapping', 'extract_license', 'api_url='
609+
, 'api_username=', 'api_key=']
467610
try:
468611
opts, args = getopt.getopt(sys.argv[1:], 'hv', longopts)
469612
except Exception as e:

0 commit comments

Comments
 (0)