linkmerce 0.3.2__tar.gz → 0.3.3__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.
Files changed (63) hide show
  1. {linkmerce-0.3.2 → linkmerce-0.3.3}/PKG-INFO +1 -1
  2. {linkmerce-0.3.2 → linkmerce-0.3.3}/pyproject.toml +1 -1
  3. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/.DS_Store +0 -0
  4. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/load.py +8 -3
  5. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/openapi/search/models.sql +3 -0
  6. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/manage/exposure/models.sql +4 -2
  7. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/manage/exposure/transform.py +4 -0
  8. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/tqdm.py +2 -2
  9. {linkmerce-0.3.2 → linkmerce-0.3.3}/README.md +0 -0
  10. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/__init__.py +0 -0
  11. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/api/__init__.py +0 -0
  12. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/api/naver/__init__.py +0 -0
  13. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/api/naver/openapi.py +0 -0
  14. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/api/searchad/__init__.py +0 -0
  15. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/api/searchad/manage.py +0 -0
  16. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/api/smartstore/__init__.py +0 -0
  17. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/api/smartstore/brand.py +0 -0
  18. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/.DS_Store +0 -0
  19. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/__init__.py +0 -0
  20. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/api.py +0 -0
  21. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/exceptions.py +0 -0
  22. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/extract.py +0 -0
  23. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/models.py +0 -0
  24. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/tasks.py +0 -0
  25. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/common/transform.py +0 -0
  26. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/.DS_Store +0 -0
  27. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/__init__.py +0 -0
  28. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/.DS_Store +0 -0
  29. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/__init__.py +0 -0
  30. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/openapi/.DS_Store +0 -0
  31. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/openapi/__init__.py +0 -0
  32. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/openapi/common.py +0 -0
  33. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/openapi/search/__init__.py +0 -0
  34. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/openapi/search/extract.py +0 -0
  35. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/naver/openapi/search/transform.py +0 -0
  36. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/.DS_Store +0 -0
  37. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/__init__.py +0 -0
  38. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/manage/.DS_Store +0 -0
  39. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/manage/__init__.py +0 -0
  40. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/manage/common.py +0 -0
  41. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/manage/exposure/__init__.py +0 -0
  42. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/searchad/manage/exposure/extract.py +0 -0
  43. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/.DS_Store +0 -0
  44. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/__init__.py +0 -0
  45. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/.DS_Store +0 -0
  46. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/__init__.py +0 -0
  47. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/catalog/__init__.py +0 -0
  48. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/catalog/extract.py +0 -0
  49. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/catalog/models.sql +0 -0
  50. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/catalog/transform.py +0 -0
  51. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/common.py +0 -0
  52. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/sales/__init__.py +0 -0
  53. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/sales/extract.py +0 -0
  54. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/sales/models.sql +0 -0
  55. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/core/smartstore/brand/sales/transform.py +0 -0
  56. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/.DS_Store +0 -0
  57. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/__init__.py +0 -0
  58. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/cast.py +0 -0
  59. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/date.py +0 -0
  60. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/graphql.py +0 -0
  61. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/headers.py +0 -0
  62. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/jinja.py +0 -0
  63. {linkmerce-0.3.2 → linkmerce-0.3.3}/src/linkmerce/utils/map.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: linkmerce
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: E-commerce API integration management
5
5
  Requires-Dist: aiohttp>=3.12.15
6
6
  Requires-Dist: bs4>=0.0.2
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "linkmerce"
3
- version = "0.3.2"
3
+ version = "0.3.3"
4
4
  description = "E-commerce API integration management"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -179,8 +179,8 @@ class Connection(metaclass=ABCMeta):
179
179
  ###################################################################
180
180
 
181
181
  class DuckDBConnection(Connection):
182
- def __init__(self, **kwargs):
183
- self.set_connection(**kwargs)
182
+ def __init__(self, tzinfo: str | None = None, **kwargs):
183
+ self.set_connection(tzinfo, **kwargs)
184
184
 
185
185
  @property
186
186
  def conn(self) -> DuckDBPyConnection:
@@ -189,9 +189,11 @@ class DuckDBConnection(Connection):
189
189
  def get_connection(self) -> DuckDBPyConnection:
190
190
  return self.__conn
191
191
 
192
- def set_connection(self, **kwargs):
192
+ def set_connection(self, tzinfo: str | None = None, **kwargs):
193
193
  import duckdb
194
194
  self.__conn = duckdb.connect(**kwargs)
195
+ if tzinfo is not None:
196
+ self.conn.execute(f"SET TimeZone = '{tzinfo}';")
195
197
 
196
198
  def close(self):
197
199
  try:
@@ -495,6 +497,9 @@ class DuckDBConnection(Connection):
495
497
  return bool(self.conn.execute(query).fetchone())
496
498
  return False
497
499
 
500
+ def count_table(self, table: str) -> int:
501
+ return self.conn.execute(f"SELECT COUNT(*) FROM {table}").fetchall()[0][0]
502
+
498
503
  def get_columns(self, obj: str | DuckDBPyConnection) -> list[str]:
499
504
  if isinstance(obj, str):
500
505
  obj = self.conn.execute(f"DESCRIBE {obj}")
@@ -240,6 +240,7 @@ CREATE OR REPLACE TABLE {{ table }} (
240
240
  nvMid BIGINT PRIMARY KEY
241
241
  , mallPid BIGINT
242
242
  , productName VARCHAR
243
+ , wholeCategoryName VARCHAR
243
244
  , mallName VARCHAR
244
245
  , brandName VARCHAR
245
246
  , updatedAt TIMESTAMP NOT NULL
@@ -250,6 +251,7 @@ SELECT
250
251
  TRY_CAST(productId AS BIGINT) AS nvMid
251
252
  , TRY_CAST(REGEXP_EXTRACT(link, '/products/(\d+)$', 1) AS BIGINT) AS mallPid
252
253
  , REGEXP_REPLACE(title, '<[^>]+>', '', 'g') AS productName
254
+ , CONCAT_WS('>', category1, category2, category3, category4) AS wholeCategoryName
253
255
  , NULLIF(mallName, '네이버') AS mallName
254
256
  , NULLIF(brand, '') AS brandName
255
257
  , CAST(DATE_TRUNC('second', CURRENT_TIMESTAMP) AS TIMESTAMP) AS updatedAt
@@ -261,6 +263,7 @@ INSERT INTO {{ table }} {{ values }}
261
263
  ON CONFLICT DO UPDATE SET
262
264
  mallPid = COALESCE(excluded.mallPid, mallPid)
263
265
  , productName = COALESCE(excluded.productName, productName)
266
+ , wholeCategoryName = COALESCE(excluded.wholeCategoryName, wholeCategoryName)
264
267
  , mallName = COALESCE(excluded.mallName, mallName)
265
268
  , brandName = COALESCE(excluded.brandName, brandName)
266
269
  , updatedAt = excluded.updatedAt;
@@ -29,7 +29,7 @@ SELECT
29
29
  , NULLIF(fmpBrand, '') AS mallName
30
30
  , NULLIF(fmpMaker, '') AS makerName
31
31
  , imageUrl
32
- , TRY_CAST(COALESCE(lowPrice, mobileLowPrice, NULL) AS INTEGER) AS salesPrice
32
+ , TRY_CAST(COALESCE(lowPrice, mobileLowPrice) AS INTEGER) AS salesPrice
33
33
  FROM {{ array }}
34
34
  WHERE ($is_own IS NULL) OR (isOwn = $is_own);
35
35
 
@@ -71,6 +71,7 @@ INSERT INTO {{ table }} {{ values }} ON CONFLICT DO NOTHING;
71
71
  CREATE OR REPLACE TABLE {{ table }} (
72
72
  productId BIGINT PRIMARY KEY
73
73
  , isNvMid BOOLEAN
74
+ , mallPid BIGINT
74
75
  , productName VARCHAR
75
76
  , wholeCategoryName VARCHAR
76
77
  , mallName VARCHAR
@@ -89,10 +90,11 @@ FROM (
89
90
  TRY_CAST(TRY_CAST(FROM_BASE64(REGEXP_EXTRACT(imageUrl, '^https://[^/]+/[^/]+/([^.]+)', 1)) AS VARCHAR) AS BIGINT)
90
91
  ELSE NULL END) AS productId
91
92
  , PREFIX(imageUrl, 'https://shopping-') AS isNvMid
93
+ , NULL AS mallPid
92
94
  , productTitle AS productName
93
95
  , categoryNames AS wholeCategoryName
94
96
  , NULLIF(fmpBrand, '') AS mallName
95
- , TRY_CAST(COALESCE(lowPrice, mobileLowPrice, NULL) AS INTEGER) AS salesPrice
97
+ , TRY_CAST(COALESCE(lowPrice, mobileLowPrice) AS INTEGER) AS salesPrice
96
98
  , CAST(DATE_TRUNC('second', CURRENT_TIMESTAMP) AS TIMESTAMP) AS updatedAt
97
99
  FROM {{ array }}
98
100
  WHERE ($is_own IS NULL) OR (isOwn = $is_own)
@@ -52,8 +52,12 @@ class ExposureRank(ExposureDiagnosis):
52
52
  params: dict = dict(),
53
53
  **kwargs
54
54
  ) -> tuple[DuckDBPyRelation,DuckDBPyRelation]:
55
+ def reparse_object(obj: list[dict]) -> list[dict]:
56
+ obj[0] = dict(obj[0], lowPrice=obj[0].get("lowPrice", None), mobileLowPrice=obj[0].get("mobileLowPrice", None))
57
+ return obj
55
58
  def split_params(keyword: str, is_own: bool | None = None, **kwargs) -> tuple[dict,dict]:
56
59
  return dict(keyword=keyword, is_own=is_own), dict(is_own=is_own)
60
+ obj = reparse_object(obj)
57
61
  rank_params, product_params = split_params(**params)
58
62
  rank = super().insert_into_table(obj, key="insert_rank", table=rank_table, values=":select_rank:", params=rank_params)
59
63
  product = super().insert_into_table(obj, key="upsert_product", table=product_table, values=":select_product:", params=product_params)
@@ -10,7 +10,7 @@ if TYPE_CHECKING:
10
10
 
11
11
 
12
12
  ###################################################################
13
- ############################## Select #############################
13
+ ############################## Gather #############################
14
14
  ###################################################################
15
15
 
16
16
  def gather(
@@ -81,7 +81,7 @@ def _get_seconds(value: Real | Sequence[Real,Real]) -> Real:
81
81
 
82
82
 
83
83
  ###################################################################
84
- ############################## Select #############################
84
+ ############################## Expand #############################
85
85
  ###################################################################
86
86
 
87
87
  def expand(
File without changes