tgshops-integrations 1.0__py3-none-any.whl → 1.1__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.
- tgshops_integrations/middlewares/gateway.py +25 -29
- tgshops_integrations/nocodb_connector/model_mapping.py +52 -35
- {tgshops_integrations-1.0.dist-info → tgshops_integrations-1.1.dist-info}/METADATA +1 -1
- {tgshops_integrations-1.0.dist-info → tgshops_integrations-1.1.dist-info}/RECORD +6 -6
- {tgshops_integrations-1.0.dist-info → tgshops_integrations-1.1.dist-info}/WHEEL +0 -0
- {tgshops_integrations-1.0.dist-info → tgshops_integrations-1.1.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ from pathlib import Path
|
|
5
5
|
from aiocache import cached
|
6
6
|
from tgshops_integrations.models.products import ProductModel
|
7
7
|
from tgshops_integrations.nocodb_connector.client import NocodbClient
|
8
|
+
|
8
9
|
from tgshops_integrations.nocodb_connector.model_mapping import dump_product_data,dump_product_data_with_check, get_pagination_info, ID_FIELD, \
|
9
10
|
parse_product_data, PRODUCT_CATEGORY_ID_LOOKUP_FIELD, PRODUCT_NAME_FIELD, PRODUCT_PRICE_FIELD, \
|
10
11
|
PRODUCT_STOCK_FIELD
|
@@ -16,41 +17,35 @@ from tgshops_integrations.nocodb_connector.tables import *
|
|
16
17
|
|
17
18
|
from loguru import logger
|
18
19
|
|
19
|
-
# Step 1: Define the path to config.py (one level above)
|
20
|
-
config_path = Path(__file__).resolve().parent.parent / '../config.py'
|
21
|
-
|
22
|
-
# Step 2: Load config.py dynamically using importlib
|
23
|
-
spec = importlib.util.spec_from_file_location("config", config_path)
|
24
|
-
config = importlib.util.module_from_spec(spec)
|
25
|
-
spec.loader.exec_module(config)
|
26
|
-
|
27
|
-
# Step 3: Access variables from config.py
|
28
|
-
NOCODB_CATEGORIES = config.NOCODB_CATEGORIES
|
29
|
-
NOCODB_PRODUCTS = config.NOCODB_PRODUCTS
|
30
|
-
NOCODB_STATUSES = config.NOCODB_STATUSES
|
31
|
-
NOCODB_BOT_MESSAGES = config.NOCODB_BOT_MESSAGES
|
32
|
-
NOCODB_ORDERS = config.NOCODB_ORDERS
|
33
|
-
|
34
20
|
class Gateway(NocodbClient):
|
35
21
|
|
36
|
-
def __init__(self,logging=False,NOCODB_HOST=None,NOCODB_API_KEY=None,SOURCE=None,filter_buttons=[],special_attributes=False):
|
22
|
+
def __init__(self,logging=False,NOCODB_HOST=None,NOCODB_API_KEY=None,SOURCE=None,filter_buttons=[],config_path=None,special_attributes=False):
|
37
23
|
super().__init__(NOCODB_HOST=NOCODB_HOST,NOCODB_API_KEY=NOCODB_API_KEY,SOURCE=SOURCE)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
self.
|
24
|
+
if config_path:
|
25
|
+
self.load_config_from_path(config_path)
|
26
|
+
|
27
|
+
self.logging = logging
|
28
|
+
self.required_fields = [self.config.PRODUCT_NAME_FIELD, self.config.PRODUCT_PRICE_FIELD]
|
42
29
|
self.projection = []
|
43
|
-
self.special_attributes=special_attributes
|
44
|
-
self.filter_buttons=filter_buttons
|
30
|
+
self.special_attributes = special_attributes
|
31
|
+
self.filter_buttons = filter_buttons
|
32
|
+
|
33
|
+
def load_config_from_path(self,config_path):
|
34
|
+
if config_path.exists():
|
35
|
+
spec = importlib.util.spec_from_file_location("config", config_path)
|
36
|
+
self.config = importlib.util.module_from_spec(spec)
|
37
|
+
spec.loader.exec_module(self.config)
|
38
|
+
else:
|
39
|
+
raise FileNotFoundError(f"Configuration file not found at {config_path}")
|
45
40
|
|
46
41
|
async def load_data(self,SOURCE=None):
|
47
42
|
self.SOURCE=SOURCE
|
48
43
|
await self.get_all_tables()
|
49
|
-
self.category_manager=CategoryManager(table_id=self.tables_list[NOCODB_CATEGORIES],NOCODB_HOST=self.NOCODB_HOST,NOCODB_API_KEY=self.NOCODB_API_KEY,logging=True,filter_buttons=self.filter_buttons)
|
50
|
-
self.product_manager=ProductManager(table_id=self.tables_list[NOCODB_PRODUCTS],NOCODB_HOST=self.NOCODB_HOST,NOCODB_API_KEY=self.NOCODB_API_KEY,logging=True)
|
44
|
+
self.category_manager=CategoryManager(table_id=self.tables_list[self.config.NOCODB_CATEGORIES],NOCODB_HOST=self.NOCODB_HOST,NOCODB_API_KEY=self.NOCODB_API_KEY,logging=True,filter_buttons=self.filter_buttons)
|
45
|
+
self.product_manager=ProductManager(table_id=self.tables_list[self.config.NOCODB_PRODUCTS],NOCODB_HOST=self.NOCODB_HOST,NOCODB_API_KEY=self.NOCODB_API_KEY,logging=True)
|
51
46
|
|
52
47
|
async def create_product(self,product: ProductModel) -> ProductModel:
|
53
|
-
products_table = self.tables_list[NOCODB_PRODUCTS]
|
48
|
+
products_table = self.tables_list[self.config.NOCODB_PRODUCTS]
|
54
49
|
data = dump_product_data_with_check(data=product ,data_check=self.category_manager.categories)
|
55
50
|
# product_json = dump_product_data_with_check(data=product,data_check=self.categories)
|
56
51
|
external_id = data.pop("ID")
|
@@ -80,7 +75,7 @@ class Gateway(NocodbClient):
|
|
80
75
|
return actual_products
|
81
76
|
|
82
77
|
async def update_products(self, external_products: List[ProductModel]):
|
83
|
-
products_table = self.tables_list[NOCODB_PRODUCTS]
|
78
|
+
products_table = self.tables_list[self.config.NOCODB_PRODUCTS]
|
84
79
|
await self.product_manager.update_attributes(products=external_products)
|
85
80
|
# Updates categories if there were a new ones created
|
86
81
|
external_products=await self.category_manager.map_categories(external_products=external_products)
|
@@ -99,7 +94,7 @@ class Gateway(NocodbClient):
|
|
99
94
|
await self.create_product(product=product)
|
100
95
|
|
101
96
|
async def update_product(self, product: ProductModel):
|
102
|
-
products_table = self.tables_list[NOCODB_PRODUCTS]
|
97
|
+
products_table = self.tables_list[self.config.NOCODB_PRODUCTS]
|
103
98
|
data = dump_product_data_with_check(data=product ,data_check=self.category_manager.categories)
|
104
99
|
|
105
100
|
await self.update_table_record(
|
@@ -117,13 +112,14 @@ class Gateway(NocodbClient):
|
|
117
112
|
|
118
113
|
async def create_table_column(self, name: str, table_id: Optional[str] = None):
|
119
114
|
|
115
|
+
#TODO needs to be deleted
|
120
116
|
BEARER_TOKEN = "jpdxJtyfDXdjbvxKAcIij1HA8HGalgalLLXZ46DV"
|
121
117
|
|
122
118
|
headers = {
|
123
119
|
"Authorization": f"Bearer {BEARER_TOKEN}"
|
124
120
|
}
|
125
121
|
if not table_id:
|
126
|
-
table_id = self.tables_list[NOCODB_PRODUCTS]
|
122
|
+
table_id = self.tables_list[self.config.NOCODB_PRODUCTS]
|
127
123
|
|
128
124
|
response = await self.httpx_client.post(
|
129
125
|
f"{self.NOCODB_HOST.replace('/api/v2', '/api/v1')}/db/meta/tables/{table_id}/columns",
|
@@ -149,6 +145,6 @@ class Gateway(NocodbClient):
|
|
149
145
|
|
150
146
|
async def delete_all_products(self):
|
151
147
|
items = await self.product_manager.get_products_v2(offset=0,limit=200)
|
152
|
-
products_table = self.tables_list[NOCODB_PRODUCTS]
|
148
|
+
products_table = self.tables_list[self.config.NOCODB_PRODUCTS]
|
153
149
|
for num,item in enumerate(items):
|
154
150
|
await self.delete_table_record(products_table, item.id)
|
@@ -11,41 +11,58 @@ from tgshops_integrations.models.products import ProductModel
|
|
11
11
|
import importlib.util
|
12
12
|
from pathlib import Path
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
PRODUCT_NAME_FIELD
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
14
|
+
|
15
|
+
# Helper function to load config.py dynamically
|
16
|
+
def load_config(config_path):
|
17
|
+
config_path = Path(config_path)
|
18
|
+
if config_path.exists():
|
19
|
+
spec = importlib.util.spec_from_file_location("config", config_path)
|
20
|
+
config = importlib.util.module_from_spec(spec)
|
21
|
+
spec.loader.exec_module(config)
|
22
|
+
return config
|
23
|
+
else:
|
24
|
+
raise FileNotFoundError(f"Configuration file not found at {config_path}")
|
25
|
+
|
26
|
+
# Modify this to accept config_path dynamically
|
27
|
+
def initialize_model_mapping(config_path):
|
28
|
+
global CATEGORY_IMAGE_FIELD, ID_FIELD, CATEGORY_NAME_FIELD, CATEGORY_PARENT_ID_FIELD, CATEGORY_PARENT_FIELD,CATEGORY_ID_OF_CATEGORY_FIELD
|
29
|
+
global PRODUCT_NAME_FIELD, PRODUCT_DESCRIPTION_FIELD, PRODUCT_PRICE_FIELD, PRODUCT_CURRENCY_FIELD, PRODUCT_STOCK_FIELD
|
30
|
+
global PRODUCT_CATEGORY_NAME_FIELD, PRODUCT_CATEGORY_ID_FIELD, PRODUCT_IMAGE_FIELD, PRODUCT_DISCOUNT_PRICE_FIELD
|
31
|
+
global PRODUCT_CATEGORY_ID_LOOKUP_FIELD, PRODUCT_REQUIRED_OPTIONS_FIELD, PRODUCT_CATEGORIES_EXTRA_OPTIONS_FIELD
|
32
|
+
global PRODUCT_CATEGORIES_EXTRA_OPTION_NAMES_FIELD, PRODUCT_EXTRA_CHOICE_REQUIRED_FIELD, PRODUCT_ID_FIELD
|
33
|
+
global PRODUCT_EXTERNAL_ID, PRODUCT_CHECKOUT_MODE, NEW_ID_FIELD, NOCODB_CHECKOUT_MODES
|
34
|
+
|
35
|
+
config = load_config(config_path)
|
36
|
+
|
37
|
+
# Step 3: Load all required constants from config.py
|
38
|
+
CATEGORY_IMAGE_FIELD = config.CATEGORY_IMAGE_FIELD
|
39
|
+
ID_FIELD = config.ID_FIELD
|
40
|
+
CATEGORY_NAME_FIELD = config.CATEGORY_NAME_FIELD
|
41
|
+
CATEGORY_PARENT_ID_FIELD = config.CATEGORY_PARENT_ID_FIELD
|
42
|
+
CATEGORY_PARENT_FIELD = config.CATEGORY_PARENT_FIELD
|
43
|
+
CATEGORY_ID_OF_CATEGORY_FIELD = config.CATEGORY_ID_OF_CATEGORY_FIELD
|
44
|
+
|
45
|
+
PRODUCT_NAME_FIELD = config.PRODUCT_NAME_FIELD
|
46
|
+
PRODUCT_DESCRIPTION_FIELD = config.PRODUCT_DESCRIPTION_FIELD
|
47
|
+
PRODUCT_PRICE_FIELD = config.PRODUCT_PRICE_FIELD
|
48
|
+
PRODUCT_CURRENCY_FIELD = config.PRODUCT_CURRENCY_FIELD
|
49
|
+
PRODUCT_STOCK_FIELD = config.PRODUCT_STOCK_FIELD
|
50
|
+
PRODUCT_CATEGORY_NAME_FIELD = config.PRODUCT_CATEGORY_NAME_FIELD
|
51
|
+
|
52
|
+
PRODUCT_CATEGORY_ID_FIELD = config.PRODUCT_CATEGORY_ID_FIELD
|
53
|
+
PRODUCT_IMAGE_FIELD = config.PRODUCT_IMAGE_FIELD
|
54
|
+
PRODUCT_DISCOUNT_PRICE_FIELD = config.PRODUCT_DISCOUNT_PRICE_FIELD
|
55
|
+
PRODUCT_CATEGORY_ID_LOOKUP_FIELD = config.PRODUCT_CATEGORY_ID_LOOKUP_FIELD
|
56
|
+
PRODUCT_REQUIRED_OPTIONS_FIELD = config.PRODUCT_REQUIRED_OPTIONS_FIELD
|
57
|
+
PRODUCT_CATEGORIES_EXTRA_OPTIONS_FIELD = config.PRODUCT_CATEGORIES_EXTRA_OPTIONS_FIELD
|
58
|
+
PRODUCT_CATEGORIES_EXTRA_OPTION_NAMES_FIELD = config.PRODUCT_CATEGORIES_EXTRA_OPTION_NAMES_FIELD
|
59
|
+
PRODUCT_EXTRA_CHOICE_REQUIRED_FIELD = config.PRODUCT_EXTRA_CHOICE_REQUIRED_FIELD
|
60
|
+
PRODUCT_ID_FIELD = config.PRODUCT_ID_FIELD
|
61
|
+
PRODUCT_EXTERNAL_ID = config.PRODUCT_EXTERNAL_ID
|
62
|
+
PRODUCT_CHECKOUT_MODE = config.PRODUCT_CHECKOUT_MODE
|
63
|
+
NEW_ID_FIELD = config.NEW_ID_FIELD
|
64
|
+
|
65
|
+
NOCODB_CHECKOUT_MODES = config.NOCODB_CHECKOUT_MODES
|
49
66
|
|
50
67
|
|
51
68
|
def get_pagination_info(page_info: dict) -> PaginationResponseModel:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tgshops-integrations
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.1
|
4
4
|
Summary: Library is intended to provide the integration of the external service or CRM system with the TelegramShops/It allows to configure the relationship between NocoDB list of the products used further to display in the shop/As a resultss the products can be synchronized and updated uppon the request.
|
5
5
|
Home-page: https://git.the-devs.com/virtual-shops/shop-system/shop-backend-integrations/integration-library/integration-library
|
6
6
|
Author: Dimi Latoff
|
@@ -1,16 +1,16 @@
|
|
1
1
|
tgshops_integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
tgshops_integrations/middlewares/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
tgshops_integrations/middlewares/gateway.py,sha256=
|
3
|
+
tgshops_integrations/middlewares/gateway.py,sha256=ib7s39K9_VefobHQwtv7ajR3mTDjDziAZd00GBSZ1wA,7391
|
4
4
|
tgshops_integrations/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
tgshops_integrations/models/categories.py,sha256=EG6C8g5dOfXB2MH-vtqH13aqB7_VyOobY2FHpDb-fsY,977
|
6
6
|
tgshops_integrations/models/products.py,sha256=i0vP_eJMVCB-W25BCoodIB0AhsMTqYiDO48N-B6Ueo0,1379
|
7
7
|
tgshops_integrations/nocodb_connector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
tgshops_integrations/nocodb_connector/categories.py,sha256=YfQQ8UAkOonNZKO-oTH36vODu0eE-ElG-Me2bH5LdEM,9072
|
9
9
|
tgshops_integrations/nocodb_connector/client.py,sha256=MD08P25jYWg0ZoLGk9cZ7cH8WJ6vtMn9oXW1N0LuyZ0,11504
|
10
|
-
tgshops_integrations/nocodb_connector/model_mapping.py,sha256=
|
10
|
+
tgshops_integrations/nocodb_connector/model_mapping.py,sha256=CeGAwEZLK_NlK_eBTtsH6oRsjo6Z-QxWdC9KnwEhtPw,8770
|
11
11
|
tgshops_integrations/nocodb_connector/products.py,sha256=23uXnmznJN6fZw3tZ3a7dJg06LkI2QaNfVhSKochPn4,8677
|
12
12
|
tgshops_integrations/nocodb_connector/tables.py,sha256=ha_QXZXd93mht0fR5E1nM0wUpz1ePon-pIdO2HI67l8,356
|
13
|
-
tgshops_integrations-1.
|
14
|
-
tgshops_integrations-1.
|
15
|
-
tgshops_integrations-1.
|
16
|
-
tgshops_integrations-1.
|
13
|
+
tgshops_integrations-1.1.dist-info/METADATA,sha256=uU8JvqZdrwZETXch9M3YmqvDD_ByhPieCHMTdB1LEpU,2774
|
14
|
+
tgshops_integrations-1.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
15
|
+
tgshops_integrations-1.1.dist-info/top_level.txt,sha256=HFNtxqDpzmlF4ZLnMiwhbU7pOa_YozxU2zBl0bnUmcY,21
|
16
|
+
tgshops_integrations-1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|