Checks PMDA English 'What's New' page for device-related updates. This page (https://www.pmda.go.jp/english/0006.html) lists all recent PMDA updates with category tags (Review, Safety, Other, Events, Int, JP). Content is filtered by title_filter regex to extract device-related items onl
| 1927 | # --------------------------------------------------------------------------- |
| 1928 | |
| 1929 | class PMDAWhatsNewChecker: |
| 1930 | """Checks PMDA English 'What's New' page for device-related updates. |
| 1931 | |
| 1932 | This page (https://www.pmda.go.jp/english/0006.html) lists all recent |
| 1933 | PMDA updates with category tags (Review, Safety, Other, Events, Int, JP). |
| 1934 | Content is filtered by title_filter regex to extract device-related items only. |
| 1935 | """ |
| 1936 | |
| 1937 | def __init__(self, session: requests.Session, state: dict, |
| 1938 | seed_mode: bool = False): |
| 1939 | self.session = session |
| 1940 | self.state = state |
| 1941 | self.seed_mode = seed_mode |
| 1942 | |
| 1943 | def check(self, source_id: str, source: dict) -> Optional[dict]: |
| 1944 | url = source["url"] |
| 1945 | prev = self.state.get(source_id, {}) |
| 1946 | prev_ids = set(prev.get("seen_ids", [])) |
| 1947 | title_filter = source.get("title_filter") |
| 1948 | title_exclude = source.get("title_exclude") |
| 1949 | |
| 1950 | try: |
| 1951 | resp = self.session.get(url, timeout=30) |
| 1952 | resp.raise_for_status() |
| 1953 | except Exception as e: |
| 1954 | print(f" ERROR PMDA What's New: {e}") |
| 1955 | return None |
| 1956 | |
| 1957 | entries = self._parse_whatsnew(resp.text) |
| 1958 | if not entries: |
| 1959 | print(" WARNING: No entries from PMDA What's New page") |
| 1960 | return None |
| 1961 | |
| 1962 | print(f" INFO: Parsed {len(entries)} entries from PMDA What's New") |
| 1963 | |
| 1964 | new_items = [] |
| 1965 | all_ids = list(prev_ids) |
| 1966 | |
| 1967 | for entry in entries: |
| 1968 | eid = entry.get("link") or entry.get("title", "") |
| 1969 | if not eid or eid in prev_ids: |
| 1970 | continue |
| 1971 | title = entry.get("title", "") |
| 1972 | if title_filter and not re.search(title_filter, title, re.IGNORECASE): |
| 1973 | all_ids.append(eid) |
| 1974 | continue |
| 1975 | if title_exclude and re.search(title_exclude, title, re.IGNORECASE): |
| 1976 | all_ids.append(eid) |
| 1977 | continue |
| 1978 | all_ids.append(eid) |
| 1979 | new_items.append(entry) |
| 1980 | |
| 1981 | self.state[source_id] = { |
| 1982 | "url": url, |
| 1983 | "last_checked": datetime.now().isoformat(), |
| 1984 | "seen_ids": all_ids[-500:], |
| 1985 | } |
| 1986 |