scraper2-hj3415 2.1.0__tar.gz → 2.1.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.
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/PKG-INFO +1 -1
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/pyproject.toml +1 -1
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/main.py +41 -2
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/LICENSE +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/README.md +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/.DS_Store +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/.DS_Store +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/playwright/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/playwright/browser.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/playwright/browser_factory.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/playwright/session.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/.DS_Store +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/c101_memory_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/c103_memory_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/c104_memory_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/c106_memory_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/c108_memory_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/store.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/mongo/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/mongo/c101_mongo_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/mongo/c103_mongo_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/mongo/c104_mongo_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/mongo/c106_mongo_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/mongo/c108_mongo_sink.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/composition.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/_converters.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/_normalize.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/c101_parser.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/c103_parser.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/c104_parser.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/c106_parser.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/parsing/c108_parser.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/browser/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/browser/browser_factory_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/browser/browser_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/ingest_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/base_sink_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c101_sink_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c103_sink_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c104_sink_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c106_sink_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c108_sink_port.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c101.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c103.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c104.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c106.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c108.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/__init__.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c101.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c103.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c104.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c106.py +0 -0
- {scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c108.py +0 -0
|
@@ -92,6 +92,7 @@ async def _run_ingest_with_progress(
|
|
|
92
92
|
sleep_sec: float,
|
|
93
93
|
show: bool,
|
|
94
94
|
show_n: int,
|
|
95
|
+
asof: datetime,
|
|
95
96
|
chunk_size: int = 10,
|
|
96
97
|
progress_every: int = 1,
|
|
97
98
|
) -> None:
|
|
@@ -101,7 +102,7 @@ async def _run_ingest_with_progress(
|
|
|
101
102
|
return
|
|
102
103
|
|
|
103
104
|
t0 = time.perf_counter() # ✅ 시작 시각
|
|
104
|
-
run_asof =
|
|
105
|
+
run_asof = asof
|
|
105
106
|
|
|
106
107
|
def _chunks(xs: list[str], n: int):
|
|
107
108
|
for i in range(0, len(xs), n):
|
|
@@ -159,6 +160,39 @@ def _format_elapsed(sec: float) -> str:
|
|
|
159
160
|
h, m = divmod(m, 60)
|
|
160
161
|
return f"{h}h {m}m {s}s"
|
|
161
162
|
|
|
163
|
+
def _parse_asof(asof: str | None) -> datetime:
|
|
164
|
+
"""
|
|
165
|
+
Parse ISO8601 string to timezone-aware UTC datetime.
|
|
166
|
+
Accepts:
|
|
167
|
+
- 2026-01-09T05:00:00+00:00
|
|
168
|
+
- 2026-01-09T05:00:00Z
|
|
169
|
+
- 2026-01-09T05:00:00 (treated as UTC)
|
|
170
|
+
"""
|
|
171
|
+
if not asof:
|
|
172
|
+
return datetime.now(timezone.utc)
|
|
173
|
+
|
|
174
|
+
s = asof.strip()
|
|
175
|
+
if not s:
|
|
176
|
+
return datetime.now(timezone.utc)
|
|
177
|
+
|
|
178
|
+
# allow trailing 'Z'
|
|
179
|
+
if s.endswith("Z"):
|
|
180
|
+
s = s[:-1] + "+00:00"
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
dt = datetime.fromisoformat(s)
|
|
184
|
+
except ValueError as e:
|
|
185
|
+
raise typer.BadParameter(
|
|
186
|
+
f"--asof must be ISO8601 datetime (e.g. 2026-01-09T05:00:00Z). got={asof!r}"
|
|
187
|
+
) from e
|
|
188
|
+
|
|
189
|
+
# if naive, assume UTC
|
|
190
|
+
if dt.tzinfo is None:
|
|
191
|
+
dt = dt.replace(tzinfo=timezone.utc)
|
|
192
|
+
|
|
193
|
+
# normalize to UTC
|
|
194
|
+
return dt.astimezone(timezone.utc)
|
|
195
|
+
|
|
162
196
|
# -------------------------
|
|
163
197
|
# nfs subcommands: one / all
|
|
164
198
|
# -------------------------
|
|
@@ -170,6 +204,7 @@ def nfs_one(
|
|
|
170
204
|
sleep_sec: float = typer.Option(2.0, "--sleep"),
|
|
171
205
|
sink: Sink = typer.Option("memory", "--sink"),
|
|
172
206
|
show: bool = typer.Option(True, "--show/--no-show", help="결과 DTO 출력"),
|
|
207
|
+
asof: str | None = typer.Option(None, "--asof", help="배치 기준시각(ISO8601, UTC 권장). 예: 2026-01-09T05:00:00Z"),
|
|
173
208
|
):
|
|
174
209
|
code = code.strip()
|
|
175
210
|
if not code:
|
|
@@ -184,7 +219,7 @@ def nfs_one(
|
|
|
184
219
|
await _mongo_bootstrap(ucs.db)
|
|
185
220
|
|
|
186
221
|
try:
|
|
187
|
-
run_asof =
|
|
222
|
+
run_asof = _parse_asof(asof)
|
|
188
223
|
for ep in _endpoint_list(endpoint):
|
|
189
224
|
ingest_uc = cast(IngestPort, getattr(ucs.ingest, ep))
|
|
190
225
|
results = await ingest_uc.execute_many([code], sleep_sec=sleep_sec, asof=run_asof)
|
|
@@ -214,6 +249,7 @@ def nfs_all(
|
|
|
214
249
|
chunk_size: int = typer.Option(5, "--chunk", help="진행률 표시용 배치 크기"),
|
|
215
250
|
show: bool = typer.Option(False, "--show/--no-show", help="일부 코드만 출력"),
|
|
216
251
|
show_n: int = typer.Option(3, "--show-n"),
|
|
252
|
+
asof: str | None = typer.Option(None, "--asof", help="배치 기준시각(ISO8601). 예: 2026-01-09T05:00:00Z"),
|
|
217
253
|
):
|
|
218
254
|
async def _run():
|
|
219
255
|
ucs = build_usecases(sink_kind=sink)
|
|
@@ -228,6 +264,8 @@ def nfs_all(
|
|
|
228
264
|
if limit and limit > 0:
|
|
229
265
|
codes = codes[:limit]
|
|
230
266
|
|
|
267
|
+
run_asof = _parse_asof(asof)
|
|
268
|
+
|
|
231
269
|
typer.echo(f"\n=== NFS ALL === universe={universe}, endpoint={endpoint}, codes={len(codes)}, sink={sink}")
|
|
232
270
|
|
|
233
271
|
try:
|
|
@@ -238,6 +276,7 @@ def nfs_all(
|
|
|
238
276
|
sleep_sec=sleep_sec,
|
|
239
277
|
show=show,
|
|
240
278
|
show_n=show_n,
|
|
279
|
+
asof=run_asof,
|
|
241
280
|
chunk_size=chunk_size,
|
|
242
281
|
progress_every=1, # chunk마다
|
|
243
282
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/playwright/__init__.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/playwright/browser.py
RENAMED
|
File without changes
|
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/playwright/session.py
RENAMED
|
File without changes
|
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/memory/store.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/adapters/out/sinks/mongo/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/browser/browser_port.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/base_sink_port.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c101_sink_port.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c103_sink_port.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c104_sink_port.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c106_sink_port.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/ports/sinks/c108_sink_port.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c101.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c103.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c104.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c106.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/fetch/fetch_c108.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/__init__.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c101.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c103.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c104.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c106.py
RENAMED
|
File without changes
|
{scraper2_hj3415-2.1.0 → scraper2_hj3415-2.1.1}/src/scraper2/app/usecases/ingest/ingest_c108.py
RENAMED
|
File without changes
|