mirror of https://github.com/eyhc1/rendercv.git
add DOI validator
This commit is contained in:
parent
d08a30f800
commit
726e03fa05
|
@ -12,11 +12,13 @@ from typing_extensions import Annotated, Optional
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
from pydantic import (
|
from pydantic import (
|
||||||
BaseModel,
|
BaseModel,
|
||||||
HttpUrl,
|
HttpUrl,
|
||||||
Field,
|
Field,
|
||||||
|
field_validator,
|
||||||
model_validator,
|
model_validator,
|
||||||
computed_field,
|
computed_field,
|
||||||
EmailStr,
|
EmailStr,
|
||||||
|
@ -120,14 +122,21 @@ def compute_time_span_string(start_date: Date, end_date: Date) -> str:
|
||||||
Returns:
|
Returns:
|
||||||
str: The time span string.
|
str: The time span string.
|
||||||
"""
|
"""
|
||||||
# calculate the number of days between start_date and end_date:
|
# check if the types of start_date and end_date are correct:
|
||||||
timespan_in_days = (end_date - start_date).days
|
if not isinstance(start_date, Date):
|
||||||
|
raise TypeError("start_date is not a Date object!")
|
||||||
|
if not isinstance(end_date, Date):
|
||||||
|
raise TypeError("end_date is not a Date object!")
|
||||||
|
|
||||||
if timespan_in_days < 0:
|
# # check if start_date is before end_date:
|
||||||
|
if start_date > end_date:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"The start date is after the end date. Please check the dates!"
|
"The start date is after the end date. Please check the dates!"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# calculate the number of days between start_date and end_date:
|
||||||
|
timespan_in_days = (end_date - start_date).days
|
||||||
|
|
||||||
# calculate the number of years between start_date and end_date:
|
# calculate the number of years between start_date and end_date:
|
||||||
how_many_years = timespan_in_days // 365
|
how_many_years = timespan_in_days // 365
|
||||||
if how_many_years == 0:
|
if how_many_years == 0:
|
||||||
|
@ -469,6 +478,20 @@ class Event(BaseModel):
|
||||||
)
|
)
|
||||||
url: Optional[HttpUrl] = None
|
url: Optional[HttpUrl] = None
|
||||||
|
|
||||||
|
@field_validator("date")
|
||||||
|
@classmethod
|
||||||
|
def check_date(cls, date: str | PastDate) -> str | PastDate:
|
||||||
|
if isinstance(date, str):
|
||||||
|
try:
|
||||||
|
# If this runs, it means the date is an ISO format string, and it can be
|
||||||
|
# parsed
|
||||||
|
date = Date.fromisoformat(date)
|
||||||
|
except ValueError:
|
||||||
|
# Then it means it is a custom string like "Fall 2023"
|
||||||
|
date = date
|
||||||
|
|
||||||
|
return date
|
||||||
|
|
||||||
@model_validator(mode="after")
|
@model_validator(mode="after")
|
||||||
@classmethod
|
@classmethod
|
||||||
def check_dates(cls, model):
|
def check_dates(cls, model):
|
||||||
|
@ -735,14 +758,6 @@ class PublicationEntry(Event):
|
||||||
description="The authors of the publication in order as a list of strings.",
|
description="The authors of the publication in order as a list of strings.",
|
||||||
examples=["John Doe", "Jane Doe"],
|
examples=["John Doe", "Jane Doe"],
|
||||||
)
|
)
|
||||||
journal: str = Field(
|
|
||||||
title="Journal",
|
|
||||||
description="The journal or the conference name.",
|
|
||||||
examples=[
|
|
||||||
"Physical Review B",
|
|
||||||
"ASME International Mechanical Engineering Congress and Exposition",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
doi: str = Field(
|
doi: str = Field(
|
||||||
title="DOI",
|
title="DOI",
|
||||||
description="The DOI of the publication.",
|
description="The DOI of the publication.",
|
||||||
|
@ -759,6 +774,25 @@ class PublicationEntry(Event):
|
||||||
description="The number of citations of the publication.",
|
description="The number of citations of the publication.",
|
||||||
examples=[10, 100],
|
examples=[10, 100],
|
||||||
)
|
)
|
||||||
|
journal: Optional[str] = Field(
|
||||||
|
title="Journal",
|
||||||
|
description="The journal or the conference name.",
|
||||||
|
examples=[
|
||||||
|
"Physical Review B",
|
||||||
|
"ASME International Mechanical Engineering Congress and Exposition",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
@field_validator("doi")
|
||||||
|
@classmethod
|
||||||
|
def check_doi(cls, doi: str) -> str:
|
||||||
|
doi_url = f"https://doi.org/{doi}"
|
||||||
|
|
||||||
|
html = urllib.request.urlopen(doi_url).read().decode("utf-8")
|
||||||
|
if "DOI NOT FOUND" in html:
|
||||||
|
raise ValueError(f"{doi} cannot be found in the DOI System.")
|
||||||
|
|
||||||
|
return doi
|
||||||
|
|
||||||
@computed_field
|
@computed_field
|
||||||
@cached_property
|
@cached_property
|
||||||
|
|
Loading…
Reference in New Issue