1+ import click
2+ import inspect
3+ from jinja2 import Template
4+ from purplship .core .utils import to_dict
5+
6+ MODELS_TEMPLATE = Template ('''
7+ {% for name, cls in classes.items() %}
8+ - <a name="{{ name }}"></a> {{ name }}
9+ | Name | Type | Description
10+ | --- | --- | --- |
11+ {% for prop, typedef in cls.__annotations__.items() %} | `{{ prop }}` | {{ typedef }} |
12+ {% endfor %}
13+ {% endfor %}
14+ ''' )
15+
16+ SERVICES_TEMPLATE = Template ('''
17+ {% for key, value in service_mappers.items() %}
18+ - <a name="services-{{ key }}"></a> {{ mappers[key]["label"] }}
19+ Code | Identifier
20+ --- | ---
21+ {% for code, name in value.items() %} | `{{ code }}` | {{ name }}
22+ {% endfor %}
23+ {% endfor %}
24+ ''' )
25+
26+ SHIPMENT_OPTIONS_TEMPLATE = Template ('''
27+ {% for key, value in option_mappers.items() %}
28+ - <a name="options-{{ key }}"></a> {{ mappers[key]["label"] }}
29+ Code | Identifier
30+ --- | ---
31+ {% for code, name in value.items() %} | `{{ code }}` | {{ name }}
32+ {% endfor %}
33+ {% endfor %}
34+ ''' )
35+
36+ SHIPMENT_PRESETS_TEMPLATE = Template ('''
37+ {% for key, value in preset_mappers.items() %}
38+ - <a name="presets-{{ key }}"></a> {{ mappers[key]["label"] }}
39+ Code | Dimensions | Note
40+ --- | --- | ---
41+ {% for code, dim in value.items() %} {{ format_dimension(code, dim) }}
42+ {% endfor %}
43+ {% endfor %}
44+ ''' )
45+
46+
47+ def format_dimension (code , dim ):
48+ return f'| `{ code } ` | { f" x " .join ([str (d ) for d in dim .values () if isinstance (d , float )]) } | { f" x " .join ([k for k in dim .keys () if isinstance (dim [k ], float )]) } '
49+
50+
51+ def import_pkg (pkg : str ):
52+ * _ , carrier , name = pkg .split ("." )
53+ return __import__ (pkg , fromlist = [name ])
54+
55+
56+ PACKAGE_MAPPERS = {
57+ 'canadapost' : {
58+ 'label' : "Canada Post" ,
59+ 'package' : import_pkg ('purplship.carriers.canadapost.units' ),
60+ 'services' : "ServiceType" ,
61+ 'options' : "OptionCode" ,
62+ 'packagePresets' : "PackagePresets"
63+ },
64+ 'dhl' : {
65+ 'label' : "DHL" ,
66+ 'package' : import_pkg ('purplship.carriers.dhl.units' ),
67+ 'services' : "Product" ,
68+ 'options' : "SpecialServiceCode" ,
69+ 'packagePresets' : "PackagePresets"
70+ },
71+ 'fedex' : {
72+ 'label' : "FedEx" ,
73+ 'package' : import_pkg ('purplship.carriers.fedex.units' ),
74+ 'services' : "ServiceType" ,
75+ 'options' : "SpecialServiceType" ,
76+ 'packagePresets' : "PackagePresets"
77+ },
78+ 'purolator' : {
79+ 'label' : "Purolator" ,
80+ 'package' : import_pkg ('purplship.carriers.purolator.units' ),
81+ 'services' : "Product" ,
82+ 'options' : "Service" ,
83+ 'packagePresets' : "PackagePresets"
84+ },
85+ 'ups' : {
86+ 'label' : "UPS" ,
87+ 'package' : import_pkg ('purplship.carriers.ups.units' ),
88+ 'services' : "ShippingServiceCode" ,
89+ 'options' : "ServiceOption" ,
90+ 'packagePresets' : "PackagePresets"
91+ }
92+ }
93+
94+
95+ @click .group ()
96+ def cli ():
97+ pass
98+
99+
100+ @cli .command ()
101+ def generate_shipment_options ():
102+ option_mappers = {
103+ key : {c .name : c .value for c in list (getattr (mapper ['package' ], mapper ['options' ]))}
104+ for key , mapper in PACKAGE_MAPPERS .items ()
105+ if mapper .get ('options' ) is not None
106+ }
107+ click .echo (SHIPMENT_OPTIONS_TEMPLATE .render (option_mappers = option_mappers , mappers = PACKAGE_MAPPERS ))
108+
109+
110+ @cli .command ()
111+ def generate_package_presets ():
112+ preset_mappers = {
113+ key : {c .name : to_dict (c .value ) for c in list (getattr (mapper ['package' ], mapper ['packagePresets' ]))}
114+ for key , mapper in PACKAGE_MAPPERS .items ()
115+ if mapper .get ('packagePresets' ) is not None
116+ }
117+ click .echo (SHIPMENT_PRESETS_TEMPLATE .render (preset_mappers = preset_mappers , mappers = PACKAGE_MAPPERS , format_dimension = format_dimension ))
118+
119+
120+ @cli .command ()
121+ def generate_services ():
122+ service_mappers = {
123+ key : {c .name : c .value for c in list (getattr (mapper ['package' ], mapper ['services' ]))}
124+ for key , mapper in PACKAGE_MAPPERS .items ()
125+ if mapper .get ('services' ) is not None
126+ }
127+ click .echo (SERVICES_TEMPLATE .render (service_mappers = service_mappers , mappers = PACKAGE_MAPPERS ))
128+
129+
130+ @cli .command ()
131+ def generate_models ():
132+ import purplship .core .models as m
133+ classes = {i : t for i , t in inspect .getmembers (m ) if inspect .isclass (t )}
134+ docstr = MODELS_TEMPLATE .render (
135+ classes = classes
136+ ).replace (
137+ "purplship.core.models." , ""
138+ ).replace (
139+ "typing." , ""
140+ ).replace (
141+ "<class '" , "`"
142+ ).replace (
143+ "'>" , "`"
144+ ).replace (
145+ "Dict" , "`dict`"
146+ )
147+
148+ for name , _ in classes .items ():
149+ cls = name .strip ()
150+ docstr = docstr .replace (
151+ f"| `{ cls } ` |" , f"| [{ cls } ](#{ cls } ) |"
152+ ).replace (
153+ f"[{ cls } ] " , f"[[{ cls } ](#{ cls } )] "
154+ )
155+
156+ click .echo (docstr )
157+
158+
159+ if __name__ == '__main__' :
160+ cli ()
0 commit comments