label-sorter 0.1__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Harilal Sunil
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,58 @@
1
+ Metadata-Version: 2.4
2
+ Name: label_sorter
3
+ Version: 0.1
4
+ Summary: Library to sort Amazon and Shopify shipping labels
5
+ Home-page: https://github.com/harilal766/Ecommerce-label-sorter
6
+ Author: Harry19967
7
+ Author-email: harilalsunil2@gmail.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license
21
+ Dynamic: license-file
22
+ Dynamic: requires-python
23
+ Dynamic: summary
24
+
25
+ # Ecom-label-sorter
26
+
27
+ ## Description:
28
+ 1. A python program to sort Amazon and Shopify pdf shipping labels.
29
+ 2. Each sorted group of orders will be stored in a dedicated pdf file which is named after the product name and quantity.
30
+ 3. On Miscellaneous orders these pdf file will be named "Mixed".
31
+ 4. All of these files will be stored inside a folder which is named after the input pdf file.
32
+
33
+ ## Reason to develop this project
34
+ Manually sorting a large PDF containing multiple orders is time-consuming and prone to human error.
35
+
36
+ # Installation
37
+ ```
38
+ pip install ecom_label_sorter
39
+ ```
40
+
41
+ # Usage
42
+ ```
43
+ from label_sorter import Label_sorter
44
+
45
+ sorter_instance = Label(pdf_path = <path to the pdf file>)
46
+
47
+ # Creating sorted pdf files
48
+ # this will create a folder named after the pdf file and will be containig sorted pdf files and summary json fle.
49
+ sorter_instance.created_sorted_pdf_files()
50
+
51
+ ```
52
+
53
+
54
+
55
+
56
+ # Classes and their descriptions
57
+
58
+ [ Label Sorter](docs/Label_Sorter.md)
@@ -0,0 +1,34 @@
1
+ # Ecom-label-sorter
2
+
3
+ ## Description:
4
+ 1. A python program to sort Amazon and Shopify pdf shipping labels.
5
+ 2. Each sorted group of orders will be stored in a dedicated pdf file which is named after the product name and quantity.
6
+ 3. On Miscellaneous orders these pdf file will be named "Mixed".
7
+ 4. All of these files will be stored inside a folder which is named after the input pdf file.
8
+
9
+ ## Reason to develop this project
10
+ Manually sorting a large PDF containing multiple orders is time-consuming and prone to human error.
11
+
12
+ # Installation
13
+ ```
14
+ pip install ecom_label_sorter
15
+ ```
16
+
17
+ # Usage
18
+ ```
19
+ from label_sorter import Label_sorter
20
+
21
+ sorter_instance = Label(pdf_path = <path to the pdf file>)
22
+
23
+ # Creating sorted pdf files
24
+ # this will create a folder named after the pdf file and will be containig sorted pdf files and summary json fle.
25
+ sorter_instance.created_sorted_pdf_files()
26
+
27
+ ```
28
+
29
+
30
+
31
+
32
+ # Classes and their descriptions
33
+
34
+ [ Label Sorter](docs/Label_Sorter.md)
@@ -0,0 +1 @@
1
+ from .core import LabelSorter
@@ -0,0 +1,162 @@
1
+ import pdfplumber, re, os,sys, logging, json
2
+ from pypdf import PdfReader, PdfWriter
3
+ from pprint import pprint
4
+ from label_sorter.platforms.ecommerce.base_label import BaseLabel
5
+ from label_sorter.platforms.ecommerce.shopify import ShopifyLabel
6
+ from label_sorter.platforms.ecommerce.amazon import AmazonLabel
7
+
8
+ logging.getLogger('pdfminer').setLevel(logging.ERROR)
9
+
10
+ class LabelSorter:
11
+ def __init__(self, pdf_path):
12
+ self.sorted_dict = {}
13
+ self.label_filepath = pdf_path
14
+ self.output_folder = self.label_filepath.replace(".pdf","")
15
+ self.platform = self.find_platform()
16
+
17
+ def find_platform(self) -> str:
18
+ platform = None
19
+ try:
20
+ with pdfplumber.open(self.label_filepath) as pdf_file:
21
+ total_pages = 0; amazon_count = 0
22
+
23
+ shopify_order_id_count, amazon_order_id_count = 0, 0
24
+
25
+ for page_index, page in enumerate(pdf_file.pages):
26
+ total_pages += 1
27
+ page_text = page.extract_text(); page_tables = page.extract_tables()
28
+
29
+ # Shopify Initializations
30
+ sh = ShopifyLabel(page_text=page_text, page_table=page_tables,page_num=0)
31
+ am = AmazonLabel(page_text=page_text, page_table=page_tables,page_num=0)
32
+
33
+ if re.findall(sh.shopify_order_id_pattern, page_text):
34
+ shopify_order_id_count += 1
35
+ elif re.findall(am.amazon_order_id_pattern, page_text):
36
+ amazon_order_id_count += 1
37
+
38
+ if total_pages == shopify_order_id_count:
39
+ platform = "Shopify"
40
+ # this condition is not complete, need to add overlap page detection
41
+ elif amazon_order_id_count > 0:
42
+ platform = "Amazon"
43
+
44
+ except FileNotFoundError:
45
+ print(f"The file {self.label_filepath} does not exist.")
46
+ except Exception as e:
47
+ print(e)
48
+ else:
49
+ return platform
50
+
51
+ def create_sorted_summary(self):
52
+ if not self.platform:
53
+ sys.exit("Unsupported Platform, exiting....")
54
+ page_debrief = None
55
+ try:
56
+ print(f"Platform : {self.platform}")
57
+ with pdfplumber.open(self.label_filepath) as pdf_file:
58
+ for page_index, page in enumerate(pdf_file.pages):
59
+ page_text = page.extract_text(); page_table = page.extract_tables()
60
+ page_number = page_index+1
61
+
62
+ #Label_instance = BaseLabel(page_text=page_text, page_table=page_table,page_num=page_number)
63
+ debriefs = {
64
+ "Shopify" : ShopifyLabel(page_text=page_text, page_table=page_table,page_num=page_number).analyze_shpy_page(),
65
+ "Amazon" : AmazonLabel(page_text=page_text, page_table=page_table,page_num=page_number).analyze_amzn_page(),
66
+ }
67
+
68
+ page_debrief = debriefs[self.platform]
69
+
70
+ print(f"{page_number} : {page_debrief}")
71
+
72
+ is_page_debrief_populated = page_debrief["order_id"] != None
73
+ # sorting summary
74
+ if self.platform and is_page_debrief_populated:
75
+ self.populate_shipment_summary(
76
+ sorting_key=page_debrief["sorting_key"], qty=page_debrief["qty"],
77
+ page_nums=[page_number - 1, page_number] if self.platform == "Amazon" else [page_number]
78
+ )
79
+
80
+ except FileNotFoundError as fe:
81
+ print(fe)
82
+ except Exception as e:
83
+ print(e)
84
+ else:
85
+ return self.sorted_dict
86
+
87
+ def populate_shipment_summary(self, sorting_key:str, page_nums:list, qty : str) -> None:
88
+ try:
89
+ # different conditions for mixed and single items
90
+ # sorting key initialization
91
+ numbers_list = None
92
+ # Adding sorting key if not present
93
+ if sorting_key not in self.sorted_dict.keys():
94
+ self.sorted_dict[sorting_key] = [] if sorting_key == "Mixed" else {}
95
+
96
+ if sorting_key == "Mixed":
97
+ numbers_list = self.sorted_dict[sorting_key]
98
+ else:
99
+ if qty not in self.sorted_dict[sorting_key].keys():
100
+ self.sorted_dict[sorting_key][qty] = []
101
+ numbers_list = self.sorted_dict[sorting_key][qty]
102
+ numbers_list += page_nums
103
+
104
+ except Exception as e:
105
+ print(e)
106
+
107
+ def create_single_pdf_file(self, pdf_name, page_numbers):
108
+ try:
109
+ reader = PdfReader(self.label_filepath); writer = PdfWriter()
110
+ print(pdf_name, page_numbers)
111
+ # adding pages to the writer
112
+ for page in page_numbers:
113
+ writer.add_page(reader.pages[page-1])
114
+
115
+ page_count = len(page_numbers)
116
+ order_count = int(page_count/2) if self.platform == "Amazon" else page_count
117
+
118
+ sorted_pdf_file = f"{re.sub(r"[\|\.]*",r"",pdf_name)} - {order_count} order{"s" if order_count > 1 else ""}.pdf"
119
+ except Exception as e:
120
+ print(e)
121
+ else:
122
+ if writer:
123
+ if sorted_pdf_file:
124
+ out_filepath = os.path.join(self.output_folder, sorted_pdf_file)
125
+ with open(out_filepath, "wb") as out_pdf:
126
+ writer.write(out_pdf)
127
+
128
+ def create_sorted_pdf_files(self):
129
+ summary_dict = self.create_sorted_summary()
130
+
131
+ #pprint(summary_dict.keys())
132
+
133
+ if len(summary_dict.keys()) == 0:
134
+ sys.exit("Cannot sort with empty summary...")
135
+
136
+ order_count = None; page_numbers = None
137
+ output_file = None
138
+
139
+ # Create output folder if not created already.
140
+ if not os.path.exists(self.output_folder):
141
+ os.makedirs(self.output_folder)
142
+ print(f"Created output folder : {self.output_folder}")
143
+
144
+ # save the summary as a json file to the output folder
145
+ with open(f"{self.output_folder}/summary.json","w") as summary_json:
146
+ json.dump(summary_dict, summary_json)
147
+
148
+ try:
149
+ print(f"Sorted Summary :")
150
+ for sorting_key, value in summary_dict.items():
151
+ # Assigning output file name and its pages according to order type
152
+ # Mixed orders
153
+ if type(value) == list:
154
+ self.create_single_pdf_file(pdf_name=sorting_key, page_numbers=value)
155
+ # single item orders
156
+ elif type(value) == dict:
157
+ #print(f"Writing Single item order",end=", ")
158
+ for qty,page_list in value.items():
159
+ #print(f"Detected more than one qty.")
160
+ self.create_single_pdf_file(pdf_name=f"{sorting_key} - {qty}", page_numbers=page_list)
161
+ except Exception as e:
162
+ print(f"Err : {e}")
@@ -0,0 +1,58 @@
1
+ Metadata-Version: 2.4
2
+ Name: label_sorter
3
+ Version: 0.1
4
+ Summary: Library to sort Amazon and Shopify shipping labels
5
+ Home-page: https://github.com/harilal766/Ecommerce-label-sorter
6
+ Author: Harry19967
7
+ Author-email: harilalsunil2@gmail.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: license
21
+ Dynamic: license-file
22
+ Dynamic: requires-python
23
+ Dynamic: summary
24
+
25
+ # Ecom-label-sorter
26
+
27
+ ## Description:
28
+ 1. A python program to sort Amazon and Shopify pdf shipping labels.
29
+ 2. Each sorted group of orders will be stored in a dedicated pdf file which is named after the product name and quantity.
30
+ 3. On Miscellaneous orders these pdf file will be named "Mixed".
31
+ 4. All of these files will be stored inside a folder which is named after the input pdf file.
32
+
33
+ ## Reason to develop this project
34
+ Manually sorting a large PDF containing multiple orders is time-consuming and prone to human error.
35
+
36
+ # Installation
37
+ ```
38
+ pip install ecom_label_sorter
39
+ ```
40
+
41
+ # Usage
42
+ ```
43
+ from label_sorter import Label_sorter
44
+
45
+ sorter_instance = Label(pdf_path = <path to the pdf file>)
46
+
47
+ # Creating sorted pdf files
48
+ # this will create a folder named after the pdf file and will be containig sorted pdf files and summary json fle.
49
+ sorter_instance.created_sorted_pdf_files()
50
+
51
+ ```
52
+
53
+
54
+
55
+
56
+ # Classes and their descriptions
57
+
58
+ [ Label Sorter](docs/Label_Sorter.md)
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ label_sorter/__init__.py
6
+ label_sorter/core.py
7
+ label_sorter.egg-info/PKG-INFO
8
+ label_sorter.egg-info/SOURCES.txt
9
+ label_sorter.egg-info/dependency_links.txt
10
+ label_sorter.egg-info/top_level.txt
11
+ tests/test_core.py
@@ -0,0 +1 @@
1
+ label_sorter
File without changes
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,26 @@
1
+ from setuptools import setup, find_packages
2
+ from pathlib import Path
3
+
4
+ this_directory = Path(__file__).parent
5
+ long_description = (this_directory / "README.md").read_text()
6
+
7
+ setup(
8
+ name="label_sorter",
9
+ version="0.1",
10
+ packages=["label_sorter"],
11
+ install_requires = [
12
+
13
+ ],
14
+ author = "Harry19967",
15
+ author_email="harilalsunil2@gmail.com",
16
+ description = "Library to sort Amazon and Shopify shipping labels",
17
+ url= "https://github.com/harilal766/Ecommerce-label-sorter",
18
+ license = "MIT",
19
+ classifiers = [
20
+ "Programming Language :: Python :: 3",
21
+ "Operating System :: OS Independent"
22
+ ],
23
+ python_requires = ">=3.9",
24
+ long_description=long_description,
25
+ long_description_content_type='text/markdown'
26
+ )
@@ -0,0 +1,26 @@
1
+ import sys, os, pytest
2
+
3
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
4
+
5
+ from filepaths import amazon_pdf, shopify_pdf
6
+ from label_sorter.core import LabelSorter
7
+
8
+ class Test_LabelSorter:
9
+ label_inst = LabelSorter(pdf_path=shopify_pdf)
10
+
11
+ files = {
12
+ "Shopify" : shopify_pdf,
13
+ "Amazon" : amazon_pdf
14
+ }
15
+
16
+ def test_find_platfrom(self):
17
+ for key,value in self.files.items():
18
+ inst = LabelSorter(pdf_path=value)
19
+ assert inst.find_platform() == key
20
+
21
+ def test_sort_label(self):
22
+ assert len(self.label_inst.create_sorted_summary().keys()) > 0
23
+
24
+
25
+ # need more tests for mixed orders and amazon qr page
26
+