Compare commits
4
Commits
b2db177554
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1aa724e90f | ||
|
|
f5186e57b5 | ||
|
|
f39a7b5a09 | ||
|
|
e6d6713169 |
+1
-1
@@ -10,7 +10,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Joplin Terminal (official npm package)
|
# Joplin Terminal (official npm package)
|
||||||
RUN npm install --loglevel=error -g joplin
|
RUN npm install --loglevel=error -g joplin@3.7.1
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY pyproject.toml requirements.txt ./
|
COPY pyproject.toml requirements.txt ./
|
||||||
|
|||||||
+1
-1
@@ -158,7 +158,7 @@ sync-only 테스트가 정상이라면 `.env`를 수정합니다.
|
|||||||
JOPLIN_WRITE_ENABLED=true
|
JOPLIN_WRITE_ENABLED=true
|
||||||
```
|
```
|
||||||
|
|
||||||
현재 IEEE key가 아직 Waiting이라면 `config.nas.yaml`에서:
|
IEEE developer application이 Waiting 또는 접근이 차단된 경우에만 `config.nas.yaml`에서 비활성화합니다:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
sources:
|
sources:
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ search:
|
|||||||
|
|
||||||
sources:
|
sources:
|
||||||
ieee:
|
ieee:
|
||||||
enabled: false # Set true after the IEEE developer application becomes Active.
|
enabled: true
|
||||||
api_key_env: IEEE_API_KEY
|
api_key_env: IEEE_API_KEY
|
||||||
base_url: https://ieeexploreapi.ieee.org/api/v1/search/articles
|
base_url: https://ieeexploreapi.ieee.org/api/v1/search/articles
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ search:
|
|||||||
|
|
||||||
sources:
|
sources:
|
||||||
ieee:
|
ieee:
|
||||||
enabled: false
|
enabled: true
|
||||||
api_key_env: IEEE_API_KEY
|
api_key_env: IEEE_API_KEY
|
||||||
base_url: https://ieeexploreapi.ieee.org/api/v1/search/articles
|
base_url: https://ieeexploreapi.ieee.org/api/v1/search/articles
|
||||||
semantic_scholar:
|
semantic_scholar:
|
||||||
|
|||||||
+27
-2
@@ -7,6 +7,31 @@ RESULT_JSON="/app/data/last_result.json"
|
|||||||
|
|
||||||
log() { printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"; }
|
log() { printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"; }
|
||||||
fail() { log "ERROR: $*"; exit 1; }
|
fail() { log "ERROR: $*"; exit 1; }
|
||||||
|
joplin_sync() {
|
||||||
|
local tmp
|
||||||
|
local status
|
||||||
|
|
||||||
|
tmp="$(mktemp)"
|
||||||
|
|
||||||
|
set +e
|
||||||
|
joplin --profile "$PROFILE" sync 2>&1 | tee "$tmp"
|
||||||
|
status=${PIPESTATUS[0]}
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [[ "$status" -ne 0 ]]; then
|
||||||
|
rm -f "$tmp"
|
||||||
|
fail "Joplin sync failed with exit code $status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -Eqi 'Last error:|(^|[[:space:]])Error:' "$tmp"; then
|
||||||
|
log "ERROR: Joplin reported a sync error:"
|
||||||
|
grep -Ei 'Last error:|(^|[[:space:]])Error:' "$tmp" || true
|
||||||
|
rm -f "$tmp"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$tmp"
|
||||||
|
}
|
||||||
|
|
||||||
: "${JOPLIN_WEBDAV_URL:?JOPLIN_WEBDAV_URL is required}"
|
: "${JOPLIN_WEBDAV_URL:?JOPLIN_WEBDAV_URL is required}"
|
||||||
: "${JOPLIN_WEBDAV_USERNAME:?JOPLIN_WEBDAV_USERNAME is required}"
|
: "${JOPLIN_WEBDAV_USERNAME:?JOPLIN_WEBDAV_USERNAME is required}"
|
||||||
@@ -33,7 +58,7 @@ fi
|
|||||||
|
|
||||||
# Pull the current remote state first. This is important when PC/mobile also use the same WebDAV target.
|
# Pull the current remote state first. This is important when PC/mobile also use the same WebDAV target.
|
||||||
log "Synchronising Joplin from WebDAV before writing..."
|
log "Synchronising Joplin from WebDAV before writing..."
|
||||||
joplin --profile "$PROFILE" sync
|
joplin_sync
|
||||||
|
|
||||||
if [[ "${JOPLIN_WRITE_ENABLED,,}" != "true" ]]; then
|
if [[ "${JOPLIN_WRITE_ENABLED,,}" != "true" ]]; then
|
||||||
log "JOPLIN_WRITE_ENABLED=false: sync-only safety mode. No paper note will be written."
|
log "JOPLIN_WRITE_ENABLED=false: sync-only safety mode. No paper note will be written."
|
||||||
@@ -86,6 +111,6 @@ log "Importing report into Joplin notebook: $JOPLIN_NOTEBOOK"
|
|||||||
joplin --profile "$PROFILE" import "$TMP_MD" "$JOPLIN_NOTEBOOK" --format md -f
|
joplin --profile "$PROFILE" import "$TMP_MD" "$JOPLIN_NOTEBOOK" --format md -f
|
||||||
|
|
||||||
log "Synchronising Joplin changes to WebDAV..."
|
log "Synchronising Joplin changes to WebDAV..."
|
||||||
joplin --profile "$PROFILE" sync
|
joplin_sync
|
||||||
|
|
||||||
log "Completed: $REPORT_TITLE ($REPORT_COUNT papers)"
|
log "Completed: $REPORT_TITLE ($REPORT_COUNT papers)"
|
||||||
|
|||||||
+24
-32
@@ -1,6 +1,6 @@
|
|||||||
# Paper Monitor 프로젝트 - 남은 작업 및 검토 TODO
|
# Paper Monitor 프로젝트 - 남은 작업 및 검토 TODO
|
||||||
|
|
||||||
최종 업데이트: 2026-08-22 (Groq API 검증 및 fallback 구현 완료 반영)
|
최종 업데이트: 2026-08-24 (IEEE API 활성화 및 전체 NAS 실행 완료 반영)
|
||||||
|
|
||||||
이 문서는 지금까지 구축한 Synology NAS 기반 논문 자동 모니터링 시스템에서 **아직 미정이거나 수행하지 못한 항목**, 그리고 **운영 전에 변경 또는 추가 검토가 필요한 항목**을 정리한 TODO 목록이다.
|
이 문서는 지금까지 구축한 Synology NAS 기반 논문 자동 모니터링 시스템에서 **아직 미정이거나 수행하지 못한 항목**, 그리고 **운영 전에 변경 또는 추가 검토가 필요한 항목**을 정리한 TODO 목록이다.
|
||||||
|
|
||||||
@@ -52,18 +52,13 @@
|
|||||||
- 검색 query 수 축소
|
- 검색 query 수 축소
|
||||||
- `max_retries` 추가 축소
|
- `max_retries` 추가 축소
|
||||||
|
|
||||||
### [x] IEEE 접근 차단 해제 여부 확인
|
### [x] IEEE API 승인·활성화 및 전체 실행 확인 (2026-08-24)
|
||||||
- 2026-08-21 확인: 집 인터넷에서 `developer.ieee.org` HTTP 200 OK - 차단 해제 완료
|
- IEEE developer application Active 및 `IEEE_API_KEY` 인증 확인.
|
||||||
- API 승인 상태 및 key 교체 여부는 아래 별도 항목에서 확인 필요
|
- `config.yaml`, `config.nas.yaml`에서 `sources.ieee.enabled: true` 적용.
|
||||||
- 재활성화 시 먼저 1개 query만 수동 테스트 권장
|
- 단일 query smoke test: IEEE Xplore API HTTP 200, JSON 응답 확인.
|
||||||
- 401 / 403 / 429 / timeout / connection error 발생 시 해당 run의 IEEE 전체 중단 유지
|
- NAS 운영 구성 전체 실행: 8개 IEEE query에서 15편 수집, 인증·rate-limit 오류 없음.
|
||||||
- 동일 run에서 IEEE 자동 retry는 하지 않음
|
- 요청 간 최소 5초 간격을 유지한다. 주 1회 8 calls/run 운영은 IEEE 한도 10 calls/s, 200 calls/day보다 충분히 낮다.
|
||||||
- 요청 간 최소 간격 5초 유지
|
- 403/429/네트워크 오류는 circuit breaker cooldown으로 후속 호출을 억제한다.
|
||||||
|
|
||||||
### [ ] IEEE API 승인 상태 확인
|
|
||||||
- 네트워크 차단 문제와 API 승인 문제는 별개
|
|
||||||
- IEEE API key가 최종 승인되었는지 확인 후 활성화
|
|
||||||
- 웹사이트 접속 정상화와 API 승인 상태를 각각 확인
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -272,15 +267,9 @@ Semantic Scholar가 다시 활성화된 뒤 실제 논문에서 `pdf_url`이 정
|
|||||||
- 404는 `not_found`로 처리, 파이프라인 중단 없이 계속 진행
|
- 404는 `not_found`로 처리, 파이프라인 중단 없이 계속 진행
|
||||||
- traceback 없이 조용히 처리
|
- traceback 없이 조용히 처리
|
||||||
|
|
||||||
### [ ] Unpaywall 실제 신규 논문 경로 검증
|
### [x] Unpaywall 실제 신규 논문 경로 검증 (2026-08-24)
|
||||||
standalone 테스트는 성공했지만 실제 신규 논문 run에서 다음 로그를 아직 충분히 확인하지 못함:
|
- 전체 NAS 실행에서 신규 논문 14편 중 DOI가 있는 10편을 Unpaywall로 조회.
|
||||||
|
- 10편 모두 `status=closed`, PDF URL 없음으로 정상 처리됐고 파이프라인은 계속 진행됐다.
|
||||||
```text
|
|
||||||
Unpaywall candidates: N / M new papers
|
|
||||||
Unpaywall resolved: status=... pdf=YES ...
|
|
||||||
```
|
|
||||||
|
|
||||||
신규 논문 발생 시 확인.
|
|
||||||
|
|
||||||
### [ ] PDF 다운로드 실패 유형 통계/로그 개선
|
### [ ] PDF 다운로드 실패 유형 통계/로그 개선
|
||||||
현재 예외처리는 되어 있음.
|
현재 예외처리는 되어 있음.
|
||||||
@@ -464,8 +453,6 @@ OA PDF
|
|||||||
### [ ] Semantic Scholar 연결/접근 안정화 후 재활성화
|
### [ ] Semantic Scholar 연결/접근 안정화 후 재활성화
|
||||||
(기존 섹션 1 참조)
|
(기존 섹션 1 참조)
|
||||||
|
|
||||||
### [x] IEEE 웹사이트/API 접근 확인 후 재활성화
|
|
||||||
- 2026-08-21: 네트워크 차단 해제 확인. API 승인 상태 및 key 교체 후 `IEEE enabled: true`로 전환 가능
|
|
||||||
|
|
||||||
### [ ] provider circuit breaker 지속 운용
|
### [ ] provider circuit breaker 지속 운용
|
||||||
현재 circuit breaker 정상 동작 중. 계속 유지.
|
현재 circuit breaker 정상 동작 중. 계속 유지.
|
||||||
@@ -473,7 +460,7 @@ OA PDF
|
|||||||
### [ ] Crossref 간헐적 네트워크 타임아웃 모니터링
|
### [ ] Crossref 간헐적 네트워크 타임아웃 모니터링
|
||||||
간헐적 타임아웃 발생 여부 실행 로그에서 주기적 확인.
|
간헐적 타임아웃 발생 여부 실행 로그에서 주기적 확인.
|
||||||
|
|
||||||
### [ ] IEEE 복구 후 source 우선순위 재정의
|
### [ ] IEEE 활성화 후 source 우선순위 재정의
|
||||||
장기 목표 예:
|
장기 목표 예:
|
||||||
```text
|
```text
|
||||||
IEEE Xplore
|
IEEE Xplore
|
||||||
@@ -554,9 +541,9 @@ pyproject.toml 변경
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 현재 운영 권장 설정
|
# 현재 운영 설정
|
||||||
|
|
||||||
현재 접근 제한 상황을 고려하면 당분간 다음 구성이 안전하다.
|
IEEE API가 활성화되어 IEEE, Crossref, Google Scholar Alert, Gemini, Unpaywall을 사용하는 현재 NAS 구성을 반영한다.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
app:
|
app:
|
||||||
@@ -567,7 +554,7 @@ app:
|
|||||||
|
|
||||||
sources:
|
sources:
|
||||||
ieee:
|
ieee:
|
||||||
enabled: false # 네트워크 차단 해제됨. API 승인 및 key 교체 확인 후 true로 전환
|
enabled: true
|
||||||
|
|
||||||
semantic_scholar:
|
semantic_scholar:
|
||||||
enabled: false
|
enabled: false
|
||||||
@@ -592,7 +579,7 @@ oa:
|
|||||||
lookback: 14일
|
lookback: 14일
|
||||||
```
|
```
|
||||||
|
|
||||||
IEEE 네트워크 차단은 해제되었으나 API 승인 상태 및 key 교체 확인 전까지 `enabled: false` 유지. 현재 Semantic Scholar도 비활성화 상태이므로 당분간 Crossref 중심으로 수집되고, DOI가 있는 신규 논문에 대해 Unpaywall OA 검색 및 Gemini 분석이 수행된다.
|
IEEE API는 Active 상태이며 `enabled: true`로 운영한다. 주 1회 실행에서 IEEE 8개 query를 요청하고, 요청 간 최소 5초 간격을 유지한다. Semantic Scholar는 계속 비활성화 상태이며, Crossref·Google Scholar Alert 수집 결과에 대해 Unpaywall OA 검색 및 Gemini 분석이 수행된다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -615,8 +602,7 @@ IEEE 네트워크 차단은 해제되었으나 API 승인 상태 및 key 교체
|
|||||||
|
|
||||||
## P1 - 소스
|
## P1 - 소스
|
||||||
- [ ] Semantic Scholar 연결/접근 안정화 후 재활성화
|
- [ ] Semantic Scholar 연결/접근 안정화 후 재활성화
|
||||||
- [x] IEEE 네트워크 차단 해제 확인 (2026-08-21)
|
- [x] IEEE API 승인 완료·활성화·전체 NAS 실행 확인 (2026-08-24, 8 queries / 15 papers)
|
||||||
- [ ] IEEE API 승인 상태 확인 및 활성화
|
|
||||||
- [ ] provider circuit breaker 지속 운용
|
- [ ] provider circuit breaker 지속 운용
|
||||||
- [ ] Crossref 간헐적 네트워크 타임아웃 모니터링
|
- [ ] Crossref 간헐적 네트워크 타임아웃 모니터링
|
||||||
|
|
||||||
@@ -640,7 +626,7 @@ IEEE 네트워크 차단은 해제되었으나 API 승인 상태 및 key 교체
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# 완료 항목 (2026-08-15 기준)
|
# 완료 항목
|
||||||
|
|
||||||
## 스케줄러 / 운영
|
## 스케줄러 / 운영
|
||||||
- [x] DSM Task Scheduler 최종 등록 확인
|
- [x] DSM Task Scheduler 최종 등록 확인
|
||||||
@@ -672,6 +658,12 @@ scheduler-YYYY-MM-DD_HH-MM-SS.log
|
|||||||
- [x] Groq dependency 정식 반영
|
- [x] Groq dependency 정식 반영
|
||||||
- [x] Gemini 실패 시 Groq fallback 동작 검증 완료
|
- [x] Gemini 실패 시 Groq fallback 동작 검증 완료
|
||||||
|
|
||||||
|
## IEEE API 활성화 (2026-08-24)
|
||||||
|
- [x] IEEE developer application Active 및 API key 인증 확인
|
||||||
|
- [x] `config.yaml`, `config.nas.yaml`에서 IEEE source 활성화
|
||||||
|
- [x] IEEE Xplore smoke test HTTP 200 JSON 응답 확인
|
||||||
|
- [x] NAS 전체 실행에서 8개 query, 15편 수집 및 rate-limit 오류 없음 확인
|
||||||
|
|
||||||
## IEEE 접근 (2026-08-21)
|
## IEEE 접근 (2026-08-21)
|
||||||
- [x] IEEE 네트워크 차단 해제 확인 (`developer.ieee.org` HTTP 200 OK)
|
- [x] IEEE 네트워크 차단 해제 확인 (`developer.ieee.org` HTTP 200 OK)
|
||||||
|
|
||||||
|
|||||||
@@ -10,5 +10,12 @@
|
|||||||
"open_until": 0.0,
|
"open_until": 0.0,
|
||||||
"reason": null,
|
"reason": null,
|
||||||
"strikes": {}
|
"strikes": {}
|
||||||
|
},
|
||||||
|
"ieee": {
|
||||||
|
"open_until": 1790933827.9323854,
|
||||||
|
"reason": "http_403",
|
||||||
|
"strikes": {
|
||||||
|
"http_403": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user