fosslight-util 2.1.28__py3-none-any.whl → 2.1.29__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -499,13 +499,39 @@ def get_download_location_for_maven(link):
499
499
 
500
500
  try:
501
501
  if link.startswith('mvnrepository.com/artifact/'):
502
- dn_loc_split = link.replace('mvnrepository.com/', '').split('/')
503
- group_id = dn_loc_split[1].replace('.', '/')
504
- dn_loc = 'https://repo1.maven.org/maven2/' + group_id + '/' + dn_loc_split[2] + '/' + dn_loc_split[3]
502
+ parts = link.replace('mvnrepository.com/artifact/', '').split('/')
503
+ if len(parts) < 2:
504
+ raise Exception('invalid mvnrepository artifact url')
505
+ group_raw = parts[0]
506
+ artifact_id = parts[1]
507
+ version = parts[2] if len(parts) > 2 and parts[2] else ''
508
+ group_path = group_raw.replace('.', '/')
509
+
510
+ repo_base = f'https://repo1.maven.org/maven2/{group_path}/{artifact_id}'
511
+ try:
512
+ urlopen(repo_base)
513
+ if version:
514
+ dn_loc = f'{repo_base}/{version}'
515
+ else:
516
+ new_link = repo_base
517
+ ret = True
518
+ return ret, new_link
519
+ except Exception:
520
+ google_base = f'https://dl.google.com/android/maven2/{group_path}/{artifact_id}'
521
+ if version:
522
+ google_sources = f'{google_base}/{version}/{artifact_id}-{version}-sources.jar'
523
+ try:
524
+ res_g = urlopen(google_sources)
525
+ if res_g.getcode() == 200:
526
+ ret = True
527
+ return ret, google_sources
528
+ except Exception:
529
+ pass
530
+ new_link = google_base
531
+ ret = True
532
+ return ret, new_link
505
533
 
506
534
  elif link.startswith('repo1.maven.org/maven2/'):
507
- dn_loc_split = link.replace('repo1.maven.org/maven2/', '').split('/')
508
-
509
535
  if link.endswith('.tar.gz') or link.endswith('.jar') or link.endswith('.tar.xz'):
510
536
  new_link = 'https://' + link
511
537
  ret = True
@@ -4,7 +4,7 @@
4
4
  # SPDX-License-Identifier: Apache-2.0
5
5
  import os
6
6
  import sys
7
- import wget
7
+ import requests
8
8
  import tarfile
9
9
  import zipfile
10
10
  import logging
@@ -58,6 +58,22 @@ def alarm_handler(signum, frame):
58
58
  raise TimeOutException(f'Timeout ({SIGNAL_TIMEOUT} sec)', 1)
59
59
 
60
60
 
61
+ def is_downloadable(url):
62
+ try:
63
+ h = requests.head(url, allow_redirects=True)
64
+ header = h.headers
65
+ content_type = header.get('content-type')
66
+ if 'text/html' in content_type.lower():
67
+ return False
68
+ content_disposition = header.get('content-disposition')
69
+ if content_disposition and 'attachment' in content_disposition.lower():
70
+ return True
71
+ return True
72
+ except Exception as e:
73
+ logger.warning(f"is_downloadable - failed: {e}")
74
+ return False
75
+
76
+
61
77
  def change_src_link_to_https(src_link):
62
78
  src_link = src_link.replace("git://", "https://")
63
79
  if src_link.endswith(".git"):
@@ -381,25 +397,30 @@ def download_wget(link, target_dir, compressed_only, checkout_to):
381
397
  link = new_link
382
398
 
383
399
  if compressed_only:
400
+ # Check if link ends with known compression extensions
384
401
  for ext in compression_extension:
385
402
  if link.endswith(ext):
386
403
  success = True
387
404
  break
388
- if not success:
389
- if pkg_type == 'cargo':
390
- success = True
391
405
  else:
392
- success = True
406
+ # If get_downloadable_url found a downloadable file, proceed
407
+ if ret:
408
+ success = True
409
+ else:
410
+ # No downloadable file found in package repositories, verify link is downloadable
411
+ if not is_downloadable(link):
412
+ raise Exception('Not a downloadable link (link:{0})'.format(link))
413
+ success = True
393
414
 
415
+ # Fallback: verify link is downloadable for compressed_only case
394
416
  if not success:
395
- raise Exception('Not supported compression type (link:{0})'.format(link))
417
+ if is_downloadable(link):
418
+ success = True
419
+ else:
420
+ raise Exception('Not a downloadable link (link:{0})'.format(link))
396
421
 
397
422
  logger.info(f"wget: {link}")
398
- if pkg_type == 'cargo':
399
- outfile = os.path.join(target_dir, f'{oss_name}.tar.gz')
400
- downloaded_file = wget.download(link, out=outfile)
401
- else:
402
- downloaded_file = wget.download(link, target_dir)
423
+ downloaded_file = download_file(link, target_dir)
403
424
  if platform.system() != "Windows":
404
425
  signal.alarm(0)
405
426
  else:
@@ -416,6 +437,49 @@ def download_wget(link, target_dir, compressed_only, checkout_to):
416
437
  return success, downloaded_file, msg, oss_name, oss_version
417
438
 
418
439
 
440
+ def download_file(url, target_dir):
441
+ local_path = ""
442
+ try:
443
+ try:
444
+ h = requests.head(url, allow_redirects=True)
445
+ final_url = h.url or url
446
+ headers = h.headers
447
+ except Exception:
448
+ final_url = url
449
+ headers = {}
450
+
451
+ with requests.get(final_url, stream=True, allow_redirects=True) as r:
452
+ r.raise_for_status()
453
+
454
+ filename = ""
455
+ cd = r.headers.get("Content-Disposition") or headers.get("Content-Disposition")
456
+ if cd:
457
+ m_star = re.search(r"filename\*=(?:UTF-8'')?([^;\r\n]+)", cd)
458
+ if m_star:
459
+ filename = urllib.parse.unquote(m_star.group(1).strip('"\''))
460
+ else:
461
+ m = re.search(r"filename=([^;\r\n]+)", cd)
462
+ if m:
463
+ filename = m.group(1).strip('"\'')
464
+ if not filename:
465
+ final_for_name = r.url or final_url
466
+ filename = os.path.basename(urllib.parse.urlparse(final_for_name).path)
467
+ if not filename:
468
+ filename = "downloaded_file"
469
+ if os.path.isdir(target_dir):
470
+ local_path = os.path.join(target_dir, filename)
471
+ else:
472
+ local_path = target_dir
473
+
474
+ with open(local_path, 'wb') as f:
475
+ for chunk in r.iter_content(chunk_size=8192):
476
+ f.write(chunk)
477
+ except Exception as e:
478
+ logger.warning(f"download_file - failed: {e}")
479
+ return None
480
+ return local_path
481
+
482
+
419
483
  def extract_compressed_dir(src_dir, target_dir, remove_after_extract=True):
420
484
  logger.debug(f"Extract Dir: {src_dir}")
421
485
  try:
@@ -450,6 +514,9 @@ def extract_compressed_file(fname, extract_path, remove_after_extract=True, comp
450
514
  decompress_bz2(fname, extract_path)
451
515
  elif fname.endswith(".whl"):
452
516
  unzip(fname, extract_path)
517
+ elif fname.endswith(".crate"):
518
+ with contextlib.closing(tarfile.open(fname, "r:gz")) as t:
519
+ t.extractall(path=extract_path)
453
520
  else:
454
521
  is_compressed_file = False
455
522
  if compressed_only:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fosslight_util
3
- Version: 2.1.28
3
+ Version: 2.1.29
4
4
  Summary: FOSSLight Util
5
5
  Home-page: https://github.com/fosslight/fosslight_util
6
6
  Download-URL: https://github.com/fosslight/fosslight_util
@@ -20,7 +20,6 @@ Requires-Dist: progress
20
20
  Requires-Dist: PyYAML
21
21
  Requires-Dist: lastversion
22
22
  Requires-Dist: coloredlogs
23
- Requires-Dist: python3-wget
24
23
  Requires-Dist: beautifulsoup4
25
24
  Requires-Dist: jsonmerge
26
25
  Requires-Dist: spdx-tools==0.8.*; sys_platform == "linux"
@@ -1,10 +1,10 @@
1
1
  fosslight_util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- fosslight_util/_get_downloadable_url.py,sha256=GNfGLJPQVHrU_eYse1flE42AgYUviGNKWZnq9sfUY9c,24473
2
+ fosslight_util/_get_downloadable_url.py,sha256=Komp1ODhqCKbnqGl7T-EDT8KmQuvgOeZ-nkV2bT7E-s,25519
3
3
  fosslight_util/compare_yaml.py,sha256=eLqqCLgERxRHN5vsnpQVMXIEU862Lx66mD_y4uMgQE4,2916
4
4
  fosslight_util/constant.py,sha256=3BzJtyxC0o5IFAhYaUW-DeTKkA6f5tDJFJTb0k5ji9Y,2418
5
5
  fosslight_util/correct.py,sha256=1WEAL-9_KhjFPLucPhv0PNN3K7avm0z8mU6sTuSyeHM,3864
6
6
  fosslight_util/cover.py,sha256=qqqKzxqFwKimal764FaugRUBcHWdeKt8af6xeK0mH8E,2040
7
- fosslight_util/download.py,sha256=t6-5NAcvCOfmi9TM7O1yp-9X11MiuKd8JdzNEZtEmqQ,20967
7
+ fosslight_util/download.py,sha256=AWwD3FWhF-bMagWINJ-Dg1VMuycXbe8VXX7qQ09YjYs,23565
8
8
  fosslight_util/exclude.py,sha256=fDmBsZJ_F7O9Oh2T-07R03XNbElo1tFaf_z01KfSAqU,2399
9
9
  fosslight_util/help.py,sha256=iyWmAaUQSHJtWv5mjFv0f3YoDVlDgEqdsDDEyImEUNc,2646
10
10
  fosslight_util/oss_item.py,sha256=8890JHb5ZoKQWAwN7Fl8badnlYatJtF4MVJz1rdS4yQ,6938
@@ -24,9 +24,9 @@ fosslight_util/write_yaml.py,sha256=QlEKoIPQsEaYERfbP53TeKgnllYzhLQWm5wYjnWtVjE,
24
24
  fosslight_util/resources/frequentLicenselist.json,sha256=GUhzK6tu7ok10fekOnmVmUgIGRC-acGABZKTNKfDyYA,4776157
25
25
  fosslight_util/resources/frequent_license_nick_list.json,sha256=ryU2C_6ZxHbz90_sUN9OvI9GXkCMLu7oGcmd9W79YYo,5005
26
26
  fosslight_util/resources/licenses.json,sha256=mK55z-bhY7Mjpj2KsO1crKGGL-X3F6MBFQJ0zLlx010,240843
27
- fosslight_util-2.1.28.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
28
- fosslight_util-2.1.28.dist-info/METADATA,sha256=9aponw8jVAsmq4_4hIgpvIYCyzSfkDcPR7h9a3tg9mo,6367
29
- fosslight_util-2.1.28.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
30
- fosslight_util-2.1.28.dist-info/entry_points.txt,sha256=0yZggRWNwDaClDG8UmUA10UFG8cVX3Jiy5gG9nW7hJs,68
31
- fosslight_util-2.1.28.dist-info/top_level.txt,sha256=2qyYWGLakgBRy4BqoBNt-I5C29tBr_e93e5e1pbuTGA,15
32
- fosslight_util-2.1.28.dist-info/RECORD,,
27
+ fosslight_util-2.1.29.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
28
+ fosslight_util-2.1.29.dist-info/METADATA,sha256=ly7MHTvS1SLfelDQIVFMcpFdD2KRwMOpOhwloOql0-c,6339
29
+ fosslight_util-2.1.29.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
30
+ fosslight_util-2.1.29.dist-info/entry_points.txt,sha256=0yZggRWNwDaClDG8UmUA10UFG8cVX3Jiy5gG9nW7hJs,68
31
+ fosslight_util-2.1.29.dist-info/top_level.txt,sha256=2qyYWGLakgBRy4BqoBNt-I5C29tBr_e93e5e1pbuTGA,15
32
+ fosslight_util-2.1.29.dist-info/RECORD,,