forked from borisovano/arti-repo-map
-
Notifications
You must be signed in to change notification settings - Fork 1
/
arti_repo_map.py
99 lines (80 loc) · 3.51 KB
/
arti_repo_map.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import json
import operator
import argparse
import requests
from requests.auth import HTTPBasicAuth
import os
import logging
MB = 1024 * 1024
my_path = os.path.dirname(os.path.realpath(__file__))
repo_info_cache_file = '{}/cached_repo.json'.format(my_path)
# Set logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)
def main(parsed_arguments):
repo_info = parsed_arguments.repo
if repo_info.startswith('http'):
logger.warning("Remote url is used")
repo_info = cache_repo_info_locally(repo_info, parsed_arguments.repo_user, parsed_arguments.repo_password)
sorted_repo_dict = parse_artifactory_repo(repo_info, parsed_arguments.url_lookup_depth)
print_sorted_repo_dict(sorted_repo_dict)
def parse_artifactory_repo(repo_info, url_lookup_depth):
with open(repo_info) as arti_json:
data = json.load(arti_json)
reposize = {}
for entry in data["files"]:
urllist = entry['uri'][1:].split('/')
urlslice = str(urllist[0:url_lookup_depth])
if not urlslice in reposize.keys():
reposize[urlslice] = 0
reposize[urlslice] = reposize[urlslice] + entry['size']
return sorted(reposize.items(), key=operator.itemgetter(1))
def print_sorted_repo_dict(sorted_x):
total_size = 0
for url, size in sorted_x:
total_size = total_size + size
size = sizeof_fmt(size)
url = '/'.join(eval(url))
print("{0:<50} - {1:<15} (Total: {2})".format(url, size, sizeof_fmt(total_size)))
def sizeof_fmt(num, suffix='B'):
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
if abs(num) < 1024.0:
return "%3.1f%s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, 'Yi', suffix)
def cache_repo_info_locally(url, user, password):
logger.info("Caching to repo information to local file: ./{}".format(repo_info_cache_file))
response = requests.get(url, auth=HTTPBasicAuth(user, password), stream=True)
# Throw an error for bad status codes
response.raise_for_status()
with open(repo_info_cache_file, 'wb') as handle:
threshold = 0
for block in response.iter_content(1024):
handle.write(block)
size = os.fstat(handle.fileno()).st_size
if size / MB > threshold:
logger.info("wrote {} MB to disk".format(int(size / MB)))
threshold = size / MB + 1
return repo_info_cache_file
if __name__ == "__main__":
# Args parsing
parser = argparse.ArgumentParser(description='Display Artifactory repos by size(with variable lookup depth)')
parser.add_argument("-d", "--depth",
default=4,
type=int,
help='artifactory url depth',
dest="url_lookup_depth")
parser.add_argument("-r", "--repo",
default="cached_repo.json",
type=str,
help="remote repo(artifactory repo info api) url or local path")
parser.add_argument("-u", "--user",
type=str,
dest="repo_user",
help="Artifactory user (used in case remote repo url provided)")
parser.add_argument("-p", "--password",
type=str,
dest="repo_password",
help="Artifactory password (used in case remote repo url provided)")
options = parser.parse_args()
main(options)