ughost 1.0.0__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.
- ughost/__init__.py +27 -0
- ughost/cli.py +89 -0
- ughost/extract.py +52 -0
- ughost/optimize.py +25 -0
- ughost/parts.py +161 -0
- ughost/utils.py +56 -0
- ughost-1.0.0.dist-info/METADATA +27 -0
- ughost-1.0.0.dist-info/RECORD +11 -0
- ughost-1.0.0.dist-info/WHEEL +5 -0
- ughost-1.0.0.dist-info/entry_points.txt +2 -0
- ughost-1.0.0.dist-info/top_level.txt +1 -0
ughost/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#==============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
#------------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
#==============================================================================
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
import utilo
|
|
13
|
+
|
|
14
|
+
from ughost.extract import images
|
|
15
|
+
from ughost.optimize import small
|
|
16
|
+
from ughost.parts import Part
|
|
17
|
+
from ughost.parts import bounding_convert
|
|
18
|
+
from ughost.parts import run
|
|
19
|
+
from ughost.utils import pdfwrite
|
|
20
|
+
|
|
21
|
+
__version__ = '0.9.1'
|
|
22
|
+
|
|
23
|
+
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
24
|
+
PROCESS = 'ughost'
|
|
25
|
+
|
|
26
|
+
INSTALLED = utilo.hasprog('gs') or utilo.hasprog('gswin64c')
|
|
27
|
+
HAS_GHOST = INSTALLED
|
ughost/cli.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2022-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import pdflog
|
|
11
|
+
import utilo
|
|
12
|
+
import utilo.cli
|
|
13
|
+
|
|
14
|
+
import ughost
|
|
15
|
+
|
|
16
|
+
DESCRIPTION = ''
|
|
17
|
+
CONFIG = utilo.ParserConfiguration(
|
|
18
|
+
inputparameter=True,
|
|
19
|
+
outputparameter=True,
|
|
20
|
+
prefix=False,
|
|
21
|
+
multiprocessed=False,
|
|
22
|
+
cacheflag=False,
|
|
23
|
+
waitingflag=False,
|
|
24
|
+
)
|
|
25
|
+
DPI = 216.0
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@utilo.saveme
|
|
29
|
+
def main():
|
|
30
|
+
inpath, outpath, dpi, pages = eval_cli()
|
|
31
|
+
write_images(
|
|
32
|
+
inpath,
|
|
33
|
+
outpath=outpath,
|
|
34
|
+
dpi=dpi,
|
|
35
|
+
pages=pages,
|
|
36
|
+
)
|
|
37
|
+
return utilo.SUCCESS
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def eval_cli():
|
|
41
|
+
parser = utilo.cli.create_parser(
|
|
42
|
+
config=CONFIG,
|
|
43
|
+
description=DESCRIPTION,
|
|
44
|
+
todo=[
|
|
45
|
+
utilo.Parameter(
|
|
46
|
+
longcut='dpi',
|
|
47
|
+
message='use 216 as default',
|
|
48
|
+
args={'default': DPI},
|
|
49
|
+
)
|
|
50
|
+
],
|
|
51
|
+
prog=ughost.PROCESS,
|
|
52
|
+
version=ughost.__version__,
|
|
53
|
+
)
|
|
54
|
+
args = utilo.parse(parser)
|
|
55
|
+
inpath, outpath = utilo.sources(args, singleinput=True) # pylint:disable=W0632
|
|
56
|
+
# It is only single path supported. Run program multiple times if more
|
|
57
|
+
# than one analysis is required.
|
|
58
|
+
inpath = inpath[0]
|
|
59
|
+
dpi = args.get('dpi', DPI)
|
|
60
|
+
pages = parse_pages(
|
|
61
|
+
args.get('pages', None),
|
|
62
|
+
inpath=inpath,
|
|
63
|
+
)
|
|
64
|
+
return inpath, outpath, dpi, pages
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def write_images(inpath, outpath, dpi: float, pages: tuple = None):
|
|
68
|
+
root = ughost.pdfwrite(
|
|
69
|
+
source=inpath,
|
|
70
|
+
dpi=dpi,
|
|
71
|
+
pages=pages,
|
|
72
|
+
)
|
|
73
|
+
written = utilo.file_list(root, include='png', absolute=True)
|
|
74
|
+
for path, filename in zip(written, pages):
|
|
75
|
+
filename = f'{str(filename).zfill(3)}.png'
|
|
76
|
+
dst = utilo.join(outpath, filename)
|
|
77
|
+
utilo.debug(f'write {dst}')
|
|
78
|
+
utilo.file_copy(path, dst=dst)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def parse_pages(pages: tuple, inpath: str) -> tuple:
|
|
82
|
+
pagecount = pdflog.pagecount(inpath)
|
|
83
|
+
if not pages:
|
|
84
|
+
return utilo.rtuple(pagecount)
|
|
85
|
+
pages = utilo.parse_pages(
|
|
86
|
+
pages[0],
|
|
87
|
+
pagecount=pagecount,
|
|
88
|
+
)
|
|
89
|
+
return pages
|
ughost/extract.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import io
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
import iamraw
|
|
14
|
+
import PIL.Image
|
|
15
|
+
import utilo
|
|
16
|
+
|
|
17
|
+
import ughost
|
|
18
|
+
|
|
19
|
+
DPI = 72
|
|
20
|
+
RENDERER = 300
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def images(source: str, boundings: iamraw.ImageInformations, dpi=DPI) -> list:
|
|
24
|
+
# ensure that bounding box matches with correct page
|
|
25
|
+
pages = sorted(set(item.page for item in boundings))
|
|
26
|
+
root = ughost.pdfwrite(source, dpi=RENDERER, pages=pages)
|
|
27
|
+
pagenr = {page: index for index, page in enumerate(pages, start=1)}
|
|
28
|
+
loaded = [
|
|
29
|
+
load_image(
|
|
30
|
+
bounding,
|
|
31
|
+
path=os.path.join(root, f'{pagenr[bounding.page]}.png'),
|
|
32
|
+
dpi=dpi,
|
|
33
|
+
) for bounding in boundings
|
|
34
|
+
]
|
|
35
|
+
return loaded
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def load_image(bounding: iamraw.ImageInformation, path: str, dpi=DPI) -> bytes:
|
|
39
|
+
raw = io.BytesIO()
|
|
40
|
+
with PIL.Image.open(path, formats=('png',)) as loaded:
|
|
41
|
+
# left, upper, right, lower
|
|
42
|
+
bounding = utilo.tuple_mult(
|
|
43
|
+
bounding.bounding,
|
|
44
|
+
value=RENDERER / dpi,
|
|
45
|
+
)
|
|
46
|
+
croped = loaded.crop(bounding)
|
|
47
|
+
croped.save(raw, format='png')
|
|
48
|
+
# rewind the buffer
|
|
49
|
+
raw.seek(0)
|
|
50
|
+
# convert to bytes
|
|
51
|
+
result = raw.getvalue()
|
|
52
|
+
return result
|
ughost/optimize.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
"""Optimize PDF
|
|
10
|
+
============
|
|
11
|
+
|
|
12
|
+
Use ughostScript to optimize pdf file.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import utilo
|
|
16
|
+
|
|
17
|
+
import ughost.utils
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def small(source: str, destination: str, pages: tuple = None):
|
|
21
|
+
pages = ughost.utils.gpages_fromtuple(pages)
|
|
22
|
+
config = '-sDEVICE=pdfwrite -dBATCH -dNOPAUSE -SAFE'
|
|
23
|
+
source = f'"{source}"'
|
|
24
|
+
cmd = f'{ughost.utils.GHOST} {config} {pages} -sOutputFile={destination} {source}'
|
|
25
|
+
utilo.run(cmd)
|
ughost/parts.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2022-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import dataclasses
|
|
11
|
+
import io
|
|
12
|
+
|
|
13
|
+
import PIL.Image
|
|
14
|
+
import PIL.ImageChops
|
|
15
|
+
import PIL.ImageDraw
|
|
16
|
+
import utilo
|
|
17
|
+
|
|
18
|
+
import ughost
|
|
19
|
+
import ughost.cli
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclasses.dataclass
|
|
23
|
+
class Part:
|
|
24
|
+
page: int = None
|
|
25
|
+
bounding: tuple = None
|
|
26
|
+
color: tuple = None
|
|
27
|
+
name: str = None
|
|
28
|
+
|
|
29
|
+
def __getitem__(self, index):
|
|
30
|
+
if not index:
|
|
31
|
+
return self.page
|
|
32
|
+
if index == 1:
|
|
33
|
+
return self.bounding
|
|
34
|
+
if index == 2:
|
|
35
|
+
return self.color
|
|
36
|
+
if index == 3:
|
|
37
|
+
return self.name
|
|
38
|
+
raise IndexError
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def run(src: str, dst: str, boundings: list) -> list:
|
|
42
|
+
result = []
|
|
43
|
+
extracted = parts(source=src, boundings=boundings)
|
|
44
|
+
for image, bounding in zip(extracted, boundings):
|
|
45
|
+
name = bounding.name
|
|
46
|
+
if name is None:
|
|
47
|
+
name = utilo.tmpname()
|
|
48
|
+
outpath = utilo.join(dst, f'{name}.png')
|
|
49
|
+
utilo.debug(outpath)
|
|
50
|
+
# TODO: SECURITY: BEFORE RELASE: USE PRIVATE LATER
|
|
51
|
+
utilo.file_replace_binary(outpath, content=image)
|
|
52
|
+
result.append(outpath)
|
|
53
|
+
return result
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# TODO: HOLY VALUE
|
|
57
|
+
DPI_PDF = 72.0
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def bounding_convert(pdf: tuple, dpi: int = ughost.cli.DPI) -> tuple:
|
|
61
|
+
"""\
|
|
62
|
+
>>> bounding_convert((120, 120, 520, 520))
|
|
63
|
+
(360.0, 360.0, 1560.0, 1560.0)
|
|
64
|
+
"""
|
|
65
|
+
assert dpi and DPI_PDF, f'invalid dpi: {dpi}, {DPI_PDF}'
|
|
66
|
+
result = utilo.tuple_mult(
|
|
67
|
+
pdf,
|
|
68
|
+
value=dpi / DPI_PDF,
|
|
69
|
+
)
|
|
70
|
+
return result
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def parts(source: str, boundings: list) -> list:
|
|
74
|
+
extracted = extract(
|
|
75
|
+
source=source,
|
|
76
|
+
boundings=boundings,
|
|
77
|
+
)
|
|
78
|
+
result = []
|
|
79
|
+
for item in boundings:
|
|
80
|
+
page, bounding = item.page, item.bounding
|
|
81
|
+
color = item.color
|
|
82
|
+
path = extracted[page]
|
|
83
|
+
part = extract_part(path, bounding, color)
|
|
84
|
+
result.append(part)
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def extract(source, boundings: list) -> dict:
|
|
89
|
+
workdir = utilo.tmpdir(root=ughost.ROOT)
|
|
90
|
+
pages = set(item[0] for item in boundings)
|
|
91
|
+
pages = sorted(pages)
|
|
92
|
+
pagesraw: str = ','.join(str(item) for item in pages)
|
|
93
|
+
cmd = f'{ughost.PROCESS} -i {source} -o {workdir} --pages={pagesraw}'
|
|
94
|
+
utilo.run(cmd)
|
|
95
|
+
files = utilo.file_list(
|
|
96
|
+
workdir,
|
|
97
|
+
absolute=True,
|
|
98
|
+
)
|
|
99
|
+
result = dict(zip(
|
|
100
|
+
pages,
|
|
101
|
+
files,
|
|
102
|
+
))
|
|
103
|
+
return result
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def extract_part(path: str, bounding: tuple, color=None) -> bytes:
|
|
107
|
+
raw = io.BytesIO()
|
|
108
|
+
with PIL.Image.open(path, formats=('png',)) as loaded:
|
|
109
|
+
size = loaded._size # pylint:disable=W0212
|
|
110
|
+
mask = create_mask(
|
|
111
|
+
bounding,
|
|
112
|
+
size=size,
|
|
113
|
+
)
|
|
114
|
+
image = PIL.ImageChops.multiply(loaded, mask)
|
|
115
|
+
image = colorize(image, color=color)
|
|
116
|
+
image.save(raw, format='png')
|
|
117
|
+
# rewind the buffer
|
|
118
|
+
raw.seek(0)
|
|
119
|
+
# convert to bytes
|
|
120
|
+
result = raw.getvalue()
|
|
121
|
+
return result
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def create_mask(bounding: tuple, size: tuple) -> PIL.Image:
|
|
125
|
+
"""Color list of rectangles defined in `bounding`."""
|
|
126
|
+
single = isinstance(bounding[0], (int, float))
|
|
127
|
+
if single:
|
|
128
|
+
bounding = [bounding]
|
|
129
|
+
image = PIL.Image.new(
|
|
130
|
+
mode='RGBA',
|
|
131
|
+
size=size,
|
|
132
|
+
)
|
|
133
|
+
draw = PIL.ImageDraw.Draw(image)
|
|
134
|
+
color = (0, 0, 0, 255)
|
|
135
|
+
for bbox in bounding:
|
|
136
|
+
# TODO: VERYIFY OVERLAPPING RECTANLGES
|
|
137
|
+
draw.rectangle(
|
|
138
|
+
bbox,
|
|
139
|
+
fill=color,
|
|
140
|
+
)
|
|
141
|
+
return image
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def colorize(image, color):
|
|
145
|
+
if color is None:
|
|
146
|
+
color = (255, 0, 0)
|
|
147
|
+
# split the image into individual bands
|
|
148
|
+
source = image.split()
|
|
149
|
+
alpha = 3
|
|
150
|
+
# select regions where alpha is selected
|
|
151
|
+
mask = source[alpha].point(lambda i: i)
|
|
152
|
+
# process the green band
|
|
153
|
+
for band, col in enumerate(color):
|
|
154
|
+
source[band].paste(
|
|
155
|
+
source[band].point(lambda i: col), # pylint:disable=cell-var-from-loop
|
|
156
|
+
None,
|
|
157
|
+
mask,
|
|
158
|
+
)
|
|
159
|
+
# build a new multiband image
|
|
160
|
+
image = PIL.Image.merge(image.mode, source)
|
|
161
|
+
return image
|
ughost/utils.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# C O P Y R I G H T
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2021-2023 by Helmut Konrad Schewe. All rights reserved.
|
|
5
|
+
# This file is property of Helmut Konrad Schewe. Any unauthorized copy,
|
|
6
|
+
# use or distribution is an offensive act against international law and may
|
|
7
|
+
# be prosecuted under federal law. Its content is company confidential.
|
|
8
|
+
# =============================================================================
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
|
|
12
|
+
import utilo
|
|
13
|
+
|
|
14
|
+
import ughost
|
|
15
|
+
|
|
16
|
+
GHOST = 'gswin64c' if utilo.iswin() else 'gs'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def pdfwrite(
|
|
20
|
+
source: str,
|
|
21
|
+
dpi: int = 300,
|
|
22
|
+
formats: str = 'pngalpha',
|
|
23
|
+
root: str = None,
|
|
24
|
+
pages: tuple = None,
|
|
25
|
+
):
|
|
26
|
+
root = utilo.tmpdir(root=ughost.ROOT) if root is None else root
|
|
27
|
+
if isinstance(pages, int): # pylint:disable=W0160
|
|
28
|
+
destination = os.path.join(root, f'{pages}.png')
|
|
29
|
+
else:
|
|
30
|
+
destination = os.path.join(root, '%d.png')
|
|
31
|
+
pages = gpages_fromtuple(pages)
|
|
32
|
+
config = f'-sDEVICE={formats} -r{dpi} -dBATCH -dNOPAUSE -SAFE'
|
|
33
|
+
source = f'"{source}"'
|
|
34
|
+
cmd = f'{GHOST} {config} {pages} -sOutputFile={destination} {source}'
|
|
35
|
+
utilo.run(cmd)
|
|
36
|
+
return root
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def gpages_fromtuple(pages: tuple = None) -> str:
|
|
40
|
+
"""\
|
|
41
|
+
>>> gpages_fromtuple((1, 2, 3))
|
|
42
|
+
'-sPageList=2,3,4'
|
|
43
|
+
>>> gpages_fromtuple()
|
|
44
|
+
''
|
|
45
|
+
"""
|
|
46
|
+
if pages is None:
|
|
47
|
+
return ''
|
|
48
|
+
if isinstance(pages, int):
|
|
49
|
+
pages = (pages,)
|
|
50
|
+
# ughost requires sorted page numbers
|
|
51
|
+
pages = sorted(pages)
|
|
52
|
+
# -sPageList=1,3,5
|
|
53
|
+
pages = utilo.tuple_plus(pages, value=1)
|
|
54
|
+
pages: str = utilo.from_tuple(pages, separator=',')
|
|
55
|
+
pages: str = f'-sPageList={pages}'
|
|
56
|
+
return pages
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ughost
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Author-email: Helmut Konrad Schewe <helmutus@outlook.com>
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/anaticulae/ughost
|
|
7
|
+
Project-URL: Repository, https://github.com/anaticulae/ughost
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
11
|
+
Requires-Python: >=3.12
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: utilo<3.0.0,>=2.107.5
|
|
14
|
+
Requires-Dist: iamraw<5.0.0,>=4.91.4
|
|
15
|
+
Requires-Dist: Pillow<13.0.0,>=12.2.0
|
|
16
|
+
Requires-Dist: pdflog<2.0.0,>=1.0.2
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: utilotest<2.0.0,>=1.0.3; extra == "dev"
|
|
19
|
+
Requires-Dist: hoverpower<2.0.0,>=1.1.0; extra == "dev"
|
|
20
|
+
Requires-Dist: upainter<2.0.0,>=1.0.0; extra == "dev"
|
|
21
|
+
|
|
22
|
+
# ughost
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
minidocks/ughostscript
|
|
26
|
+
minidocks/python
|
|
27
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
ughost/__init__.py,sha256=KrSDVN4ReaJcZhGNQlZ9kg2s-OOcpE3K62VFQIP0ssI,978
|
|
2
|
+
ughost/cli.py,sha256=RaJzpo083YwWzmDftlVWmaSrhrRyIqmJMfqvtbtIv8Q,2497
|
|
3
|
+
ughost/extract.py,sha256=mMSBRgCc7m0_sU6BW_Tse9y8qXWgz2vjXNTq3z5S5GY,1693
|
|
4
|
+
ughost/optimize.py,sha256=_wv0iBGcDvZwW44T-PhvwZEXoDrQfomxYra7xZgAIxU,964
|
|
5
|
+
ughost/parts.py,sha256=xURqlPCOhhwe2NwSi51J0TnuWucKI0kzTaMc16Zm9GE,4452
|
|
6
|
+
ughost/utils.py,sha256=WhgV7_jpBUq8liy5eU2TK-IvYy_ddjzjfCOLzmqKroo,1759
|
|
7
|
+
ughost-1.0.0.dist-info/METADATA,sha256=O-sF1vEec-eQ2w1qFn6AhWLYCKSh4H01If6O7HOUVEs,871
|
|
8
|
+
ughost-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
9
|
+
ughost-1.0.0.dist-info/entry_points.txt,sha256=vkkyU1gm3piJUkQmliNkz0R38mNuvuQcYa6z3jMO4rk,42
|
|
10
|
+
ughost-1.0.0.dist-info/top_level.txt,sha256=FodITgpiFEkTILdICCFDfFIf2DZBK8gPhh8cWnITS00,7
|
|
11
|
+
ughost-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ughost
|