From e36eea54ada8791e7f00568d3a52b4002c8621e1 Mon Sep 17 00:00:00 2001 From: malinkang Date: Thu, 25 Jan 2024 13:59:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=88=91=E7=9A=84=E8=AF=84?= =?UTF-8?q?=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 3 +- scripts/__pycache__/config.cpython-311.pyc | Bin 1602 -> 1035 bytes .../__pycache__/notion_helper.cpython-311.pyc | Bin 23993 -> 24888 bytes scripts/__pycache__/utils.cpython-311.pyc | Bin 16497 -> 16383 bytes .../__pycache__/weread_api.cpython-311.pyc | Bin 12408 -> 12408 bytes scripts/book.py | 55 +++--- scripts/config.py | 25 +-- scripts/notion_helper.py | 163 +++++++++++------- scripts/utils.py | 47 +++-- 9 files changed, 161 insertions(+), 132 deletions(-) diff --git a/requirements.txt b/requirements.txt index 08c48bf816e7..d5da2ddb0768 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,4 @@ requests notion-client github-heatmap retrying -pendulum -beautifulsoup4 \ No newline at end of file +pendulum \ No newline at end of file diff --git a/scripts/__pycache__/config.cpython-311.pyc b/scripts/__pycache__/config.cpython-311.pyc index f83849fbaed6be85c233b863b29f78eaa5796f1b..c86661ea6f5d1a78dce91a70c08943e9e2cc23a8 100644 GIT binary patch delta 449 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 diff --git a/scripts/__pycache__/utils.cpython-311.pyc b/scripts/__pycache__/utils.cpython-311.pyc index 22ae2c1ce5dcbc5d493d6b6174533fb1dd381183..30860e3d6292143a99b3c77334fb8cb35ed0dede 100644 GIT binary patch delta 1405 zcmaJ>ZA@EL7`~^sx6qche2o_RLB~KW3>(TvV2r>%esr5=OB_ZJRy*z$YN6nvxYXSO z#w@v1jOdYUKQ!s~LosG%wHWKf&%}jjOsS;A|19k1t0M9AX} zZ?a>#>@cWbvb8|%gstz0Ce#CJ%MLY{)4^`d5U<%0FXGGjVp=(Sf@-MQZMVAAhncq_ z^}Rwmjfxt~i5gKQvipHwMoUgnMWXgw4J=}q85?j5j9lNJn^z9T`PGB*p#nk9Il}El zX^sz!hFf!s2M0lvW`jZ`%{}j*m=$m(C5or<)U<%Zkr~=8a-!Bg|2`O7@XVxOuLVXa zt5`UyR9VjlUk|=E`Nm|1Y2+I3QCQSTtTdpQDqoGnA{Qza=a%LqwW2RwJ{;?ndXg;CsF}dYYx$-fX8CF$Oo?+D%qcrc8ycr#1 zEMFPCZg9v3$9Adp|8$NAx`OP9*eU6hVsXYBWb?xk(2AjKr9gJBcEsJX*^>_p#73kM z#ZtSvFLg#97?OvZ{qo7va@{DMyLs6xdu2|}F{Yo{!`h9)>CbZLh08Xo~$S_FTs5l;y zjxNtE9#5XweM^NdllFQy_W|@pn;ftIMqPCUOgsxX4GsZ{$+U_$Us`@`dSi!68!aT#C-k{g~I$hHQii^HG5 zg4Zd0M&VNmpOcTaQ{5ibuD^i&8@cb^hv8x|jo=Kq)YHWoz+5Ij^*r88b6g$x6m5>=now1SDZmif=zI5H-tL}^ delta 1442 zcmZ`&ZA=?w9KWa6qt})zFkX74FO-(DHZYKvIb6vw!^>e*<2vQ4^GTtHgYZ_Mx9KTOwHoaF>^NJNYD=imvoXC=NEjQ9wo-bCwIU9 z|Nr~H-v91)rXS4!+eaK{q425cyDCQN7HywbR@21ZJti!Py*+E7sPj~eO42ew>qQml zs>_CooQ$=lAA6F>P!t5G4+&I~ zl?%{urxTda7tR2~CRA*Hkhi03;uE<*$_=Pj*v(~x0@)M;Nj5Qu{e`-Z;I7{!m;{zY zO1%pQywLg}a^VaQv3bVa-={V7tie z44IyzF5|Q-d#R+S%tA(HWm;z1F@FY}J}A@Zn0q5&#LJj)VQz*}Yohvf?dZI)aCE+J zk3h#g(zH3l2(c4VlP;Qd(E{T*H$%t8sSNYl;OL~7;l|;qaS=*W1JcyEn6d4dx|_}0 z6K0(0%^&C`b!7MsbI<;PG*WCVv*plat^={=I>*_Pz>VY1$tQTL|Y1&Y^FH0MFTPl)@WG$4YCg(Ir(uxbzIePa3u=T|wu z##b#IUV2^a=~Meh)b6b!h5>#rfP4`B1F7_@wy0tV*0dq+6 z22)*UCRYmG$}ipx1Gt86`5T$*`0ZJgKmFesfr6HUW#A_IF(@$KW7@BDggR;eXIRaE z7C4!ctsyg1h-QFdh8Y`_P7K3u(1-QDira)W$Ap1VF)<_!XXrsV1;0gW^}OY4?1BW^ zm7V%1U`h25fVa^r4OPrf*oY#j;U2h$B8^_lrzDub%L;6~55Nr+X}Vsrj){!`}uCHD5o~+5;18lcKuc})j0OLSZz!8>&4%*FnEe|xZtma{ zq9O6XZS+*QjVZ?JSu_?t1|Fm3aCv!do*hy|C6Md!8`=slwvc}ZlJ!Hfj@)`6*+uTz l;TF-z<3Tc}-k})%(C!BNl!xtohN3!9k)`&aAN6*8{0~i8w=w_# diff --git a/scripts/__pycache__/weread_api.cpython-311.pyc b/scripts/__pycache__/weread_api.cpython-311.pyc index e6cbda1116592c539a62bd9de604936fff98ff47..373c6cdff51a825e56a938d96a5cf59b1a955a7d 100644 GIT binary patch delta 19 Zcmey7@FRh1IWI340}x!^xREQ*002jG24esK delta 19 Zcmey7@FRh1IWI340}wD7ZRE-`002M|1rq=O diff --git a/scripts/book.py b/scripts/book.py index 248fba0b8891..c76143bc63a3 100644 --- a/scripts/book.py +++ b/scripts/book.py @@ -10,16 +10,17 @@ from weread_api import WeReadApi import utils from config import ( - book_properties_name_dict, book_properties_type_dict, ) -from bs4 import BeautifulSoup from retrying import retry TAG_ICON_URL = "https://www.notion.so/icons/tag_gray.svg" USER_ICON_URL = "https://www.notion.so/icons/user-circle-filled_gray.svg" BOOK_ICON_URL = "https://www.notion.so/icons/book_gray.svg" +rating = {"poor": "⭐️", "fair": "⭐️⭐️⭐️", "good": "⭐️⭐️⭐️⭐️⭐️"} + + @retry(stop_max_attempt_number=3, wait_fixed=5000) def get_douban_url(isbn): print(f"get_douban_url {isbn} ") @@ -42,11 +43,12 @@ def get_douban_url(isbn): return None return urls[0].get("url") + def insert_book_to_notion(books, index, bookId): """插入Book到Notion""" book = {} if bookId in archive_dict: - book["archive"] = archive_dict.get(bookId) + book["书架分类"] = archive_dict.get(bookId) if bookId in notion_books: book.update(notion_books.get(bookId)) bookInfo = weread_api.get_bookinfo(bookId) @@ -70,17 +72,24 @@ def insert_book_to_notion(books, index, bookId): douban_url = get_douban_url(isbn) if douban_url: book["douban_url"] = douban_url - book["cover"] = cover - book["readingProgress"] = ( + book["封面"] = cover + book["阅读进度"] = ( 100 if (book.get("markedStatus") == 4) else book.get("readingProgress", 0) ) / 100 - markedStatus = book.get("markedStatus") + markedStatus = book.get("markedStatus") status = "想读" - if(markedStatus==4): + if markedStatus == 4: status = "已读" - elif(book.get("readingTime",0)>=60): + elif book.get("readingTime", 0) >= 60: status = "在读" - book["status"] = status + book["阅读状态"] = status + book["阅读时长"] = book.get("readingTime") + book["阅读天数"] = book.get("totalReadDay") + book["评分"] = book.get("newRating") + if book.get("newRatingDetail") and book.get("newRatingDetail").get("myRating"): + book["我的评分"] = rating.get(book.get("newRatingDetail").get("myRating")) + elif status=="已读": + book["我的评分"] = "未评分" date = None if book.get("finishedDate"): date = book.get("finishedDate") @@ -88,33 +97,35 @@ def insert_book_to_notion(books, index, bookId): date = book.get("lastReadingDate") elif book.get("readingBookDate"): date = book.get("readingBookDate") - book["date"] = date + book["时间"] = date + book["开始阅读时间"] = book.get("beginReadingDate") + book["最后阅读时间"] = book.get("lastReadingDate") if bookId not in notion_books: - book["author"] = [ + book["书名"] = book.get("title") + book["BookId"] = book.get("bookId") + book["ISBN"] = book.get("isbn") + book["链接"] = utils.get_weread_url(bookId) + book["简介"] = book.get("intro") + book["作者"] = [ notion_helper.get_relation_id( x, notion_helper.author_database_id, USER_ICON_URL ) for x in book.get("author").split(" ") ] - book["url"] = utils.get_weread_url(bookId) if book.get("categories"): - book["categories"] = [ + book["分类"] = [ notion_helper.get_relation_id( x.get("title"), notion_helper.category_database_id, TAG_ICON_URL ) for x in book.get("categories") - ] - else: - book.pop("categories",None) - book.pop("author",None) - properties = utils.get_properties( - book, book_properties_name_dict, book_properties_type_dict - ) + ] + properties = utils.get_properties(book, book_properties_type_dict) if book.get("date"): notion_helper.get_date_relation( properties, pendulum.from_timestamp(book.get("date"), tz="Asia/Shanghai"), ) + print(f"正在插入《{book.get('title')}》,一共{len(books)}本,当前是第{index+1}本。") parent = {"database_id": notion_helper.book_database_id, "type": "database_id"} if bookId in notion_books: @@ -159,6 +170,10 @@ def insert_book_to_notion(books, index, bookId): and value.get("cover") and (not value.get("cover").endswith("/0.jpg")) and (not value.get("cover").endswith("parsecover")) + and ( + value.get("status") != "已读" + or (value.get("status") == "已读" and value.get("myRating")) + ) ): not_need_sync.append(key) notebooks = weread_api.get_notebooklist() diff --git a/scripts/config.py b/scripts/config.py index 2935af824a17..a9b340ca576f 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -9,29 +9,6 @@ TITLE = "title" SELECT = "select" -book_properties_name_dict = { - "title":"书名", - "bookId":"BookId", - "isbn":"ISBN", - "url":"链接", - "author":"作者", - "Sort":"Sort", - "newRating":"评分", - "cover":"封面", - "categories":"分类", - "status":"阅读状态", - "readingTime":"阅读时长", - "readingProgress":"阅读进度", - "totalReadDay":"阅读天数", - "date":"时间", - "beginReadingDate":"开始阅读时间", - "lastReadingDate":"最后阅读时间", - "intro":"简介", - "archive":"书架分类", - "douban_url":"豆瓣链接", - "neodb_url":"NeoDB链接", -} - book_properties_type_dict = { "书名":TITLE, "BookId":RICH_TEXT, @@ -51,6 +28,6 @@ "最后阅读时间":DATE, "简介":RICH_TEXT, "书架分类":SELECT, + "我的评分":SELECT, "豆瓣链接":URL, - "NeoDB链接":URL, } diff --git a/scripts/notion_helper.py b/scripts/notion_helper.py index 4af3f62a2f85..c6f057b1858c 100644 --- a/scripts/notion_helper.py +++ b/scripts/notion_helper.py @@ -30,91 +30,129 @@ class NotionHelper: database_name_dict = { - "BOOK_DATABASE_NAME":"书架", - "REVIEW_DATABASE_NAME":"笔记", - "BOOKMARK_DATABASE_NAME":"划线", - "DAY_DATABASE_NAME":"日", - "WEEK_DATABASE_NAME":"周", - "MONTH_DATABASE_NAME":"月", - "YEAR_DATABASE_NAME":"年", - "CATEGORY_DATABASE_NAME":"分类", - "AUTHOR_DATABASE_NAME":"作者", - "CHAPTER_DATABASE_NAME":"章节", + "BOOK_DATABASE_NAME": "书架", + "REVIEW_DATABASE_NAME": "笔记", + "BOOKMARK_DATABASE_NAME": "划线", + "DAY_DATABASE_NAME": "日", + "WEEK_DATABASE_NAME": "周", + "MONTH_DATABASE_NAME": "月", + "YEAR_DATABASE_NAME": "年", + "CATEGORY_DATABASE_NAME": "分类", + "AUTHOR_DATABASE_NAME": "作者", + "CHAPTER_DATABASE_NAME": "章节", } database_id_dict = {} image_dict = {} def __init__(self): self.client = Client(auth=os.getenv("NOTION_TOKEN"), log_level=logging.ERROR) - self.__cache={} - self.search_database(self.extract_page_id(os.getenv("NOTION_PAGE"))) + self.__cache = {} + self.page_id = self.extract_page_id(os.getenv("NOTION_PAGE")) + self.search_database(self.page_id) for key in self.database_name_dict.keys(): - if(os.getenv(key)!=None and os.getenv(key)!=""): + if os.getenv(key) != None and os.getenv(key) != "": self.database_name_dict[key] = os.getenv(key) - self.book_database_id = self.database_id_dict.get(self.database_name_dict.get("BOOK_DATABASE_NAME")) - self.review_database_id = self.database_id_dict.get(self.database_name_dict.get("REVIEW_DATABASE_NAME")) - self.bookmark_database_id = self.database_id_dict.get(self.database_name_dict.get("BOOKMARK_DATABASE_NAME")) - self.day_database_id = self.database_id_dict.get(self.database_name_dict.get("DAY_DATABASE_NAME")) - self.week_database_id = self.database_id_dict.get(self.database_name_dict.get("WEEK_DATABASE_NAME")) - self.month_database_id = self.database_id_dict.get(self.database_name_dict.get("MONTH_DATABASE_NAME")) - self.year_database_id = self.database_id_dict.get(self.database_name_dict.get("YEAR_DATABASE_NAME")) - self.category_database_id = self.database_id_dict.get(self.database_name_dict.get("CATEGORY_DATABASE_NAME")) - self.author_database_id = self.database_id_dict.get(self.database_name_dict.get("AUTHOR_DATABASE_NAME")) - self.chapter_database_id = self.database_id_dict.get(self.database_name_dict.get("CHAPTER_DATABASE_NAME")) + self.book_database_id = self.database_id_dict.get( + self.database_name_dict.get("BOOK_DATABASE_NAME") + ) + self.review_database_id = self.database_id_dict.get( + self.database_name_dict.get("REVIEW_DATABASE_NAME") + ) + self.bookmark_database_id = self.database_id_dict.get( + self.database_name_dict.get("BOOKMARK_DATABASE_NAME") + ) + self.day_database_id = self.database_id_dict.get( + self.database_name_dict.get("DAY_DATABASE_NAME") + ) + self.week_database_id = self.database_id_dict.get( + self.database_name_dict.get("WEEK_DATABASE_NAME") + ) + self.month_database_id = self.database_id_dict.get( + self.database_name_dict.get("MONTH_DATABASE_NAME") + ) + self.year_database_id = self.database_id_dict.get( + self.database_name_dict.get("YEAR_DATABASE_NAME") + ) + self.category_database_id = self.database_id_dict.get( + self.database_name_dict.get("CATEGORY_DATABASE_NAME") + ) + self.author_database_id = self.database_id_dict.get( + self.database_name_dict.get("AUTHOR_DATABASE_NAME") + ) + self.chapter_database_id = self.database_id_dict.get( + self.database_name_dict.get("CHAPTER_DATABASE_NAME") + ) self.update_book_database() - def extract_page_id(self,notion_url): + def extract_page_id(self, notion_url): # 正则表达式匹配 32 个字符的 Notion page_id - match = re.search(r"([a-f0-9]{32}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})", notion_url) + match = re.search( + r"([a-f0-9]{32}|[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})", + notion_url, + ) if match: return match.group(0) else: raise Exception(f"获取NotionID失败,请检查输入的Url是否正确") - def search_database(self,block_id): + + + def search_database(self, block_id): children = self.client.blocks.children.list(block_id=block_id)["results"] # 遍历子块 for child in children: # 检查子块的类型 - + if child["type"] == "child_database": - self.database_id_dict[child.get('child_database').get('title')] = child.get("id") + self.database_id_dict[ + child.get("child_database").get("title") + ] = child.get("id") elif child["type"] == "image": - self.image_dict["url"] = child.get('image').get('external').get('url') - self.image_dict["id"] = child.get('id') + self.image_dict["url"] = child.get("image").get("external").get("url") + self.image_dict["id"] = child.get("id") # 如果子块有子块,递归调用函数 if "has_children" in child and child["has_children"]: self.search_database(child["id"]) def update_book_database(self): """更新数据库""" - response = self.client.databases.retrieve( - database_id=self.book_database_id - ) + response = self.client.databases.retrieve(database_id=self.book_database_id) id = response.get("id") properties = response.get("properties") update_properties = {} - if properties.get("阅读时长") is None or properties.get("阅读时长").get("type") != "number": + if ( + properties.get("阅读时长") is None + or properties.get("阅读时长").get("type") != "number" + ): update_properties["阅读时长"] = {"number": {}} - if properties.get("书架分类") is None or properties.get("书架分类").get("type") != "select": + if ( + properties.get("书架分类") is None + or properties.get("书架分类").get("type") != "select" + ): update_properties["书架分类"] = {"select": {}} - if properties.get("豆瓣链接") is None or properties.get("豆瓣链接").get("type") != "url": + if ( + properties.get("豆瓣链接") is None + or properties.get("豆瓣链接").get("type") != "url" + ): update_properties["豆瓣链接"] = {"url": {}} - """NeoDB先不添加了,现在受众还不光,可能有的小伙伴不知道是干什么的""" + if ( + properties.get("我的评分") is None + or properties.get("我的评分").get("type") != "select" + ): + update_properties["我的评分"] = {"select": {}} + if ( + properties.get("豆瓣短评") is None + or properties.get("豆瓣短评").get("type") != "rich_text" + ): + update_properties["豆瓣短评"] = {"rich_text": {}} + """NeoDB先不添加了,现在受众还不广,可能有的小伙伴不知道是干什么的""" # if properties.get("NeoDB链接") is None or properties.get("NeoDB链接").get("type") != "url": # update_properties["NeoDB链接"] = {"url": {}} if len(update_properties) > 0: - self.client.databases.update( - database_id=id, properties=update_properties - ) + self.client.databases.update(database_id=id, properties=update_properties) - def update_image_block_link(self,block_id, new_image_url): + def update_image_block_link(self, block_id, new_image_url): # 更新 image block 的链接 self.client.blocks.update( - block_id=block_id, - image={ - "external": { - "url": new_image_url - } - } + block_id=block_id, image={"external": {"url": new_image_url}} ) def get_week_relation_id(self, date): @@ -145,7 +183,7 @@ def get_year_relation_id(self, date): def get_day_relation_id(self, date): new_date = date.replace(hour=0, minute=0, second=0, microsecond=0) - timestamp = (new_date-timedelta(hours=8)).timestamp() + timestamp = (new_date - timedelta(hours=8)).timestamp() day = new_date.strftime("%Y年%m月%d日") properties = { "日期": get_date(format_date(date)), @@ -231,7 +269,7 @@ def insert_review(self, id, review): if "createTime" in review: create_time = timestamp_to_date(int(review.get("createTime"))) properties["Date"] = get_date(create_time.strftime("%Y-%m-%d %H:%M:%S")) - self.get_date_relation(properties,create_time) + self.get_date_relation(properties, create_time) parent = {"database_id": self.review_database_id, "type": "database_id"} self.create_page(parent, properties, icon) @@ -253,9 +291,7 @@ def insert_chapter(self, id, chapter): @retry(stop_max_attempt_number=3, wait_fixed=5000) def update_book_page(self, page_id, properties): - return self.client.pages.update( - page_id=page_id, properties=properties - ) + return self.client.pages.update(page_id=page_id, properties=properties) @retry(stop_max_attempt_number=3, wait_fixed=5000) def update_page(self, page_id, properties, icon): @@ -290,7 +326,7 @@ def append_blocks_after(self, block_id, children, after): @retry(stop_max_attempt_number=3, wait_fixed=5000) def delete_block(self, block_id): return self.client.blocks.delete(block_id=block_id) - + @retry(stop_max_attempt_number=3, wait_fixed=5000) def get_all_book(self): """从Notion中获取所有的书籍""" @@ -300,17 +336,19 @@ def get_all_book(self): bookId = get_property_value(result.get("properties").get("BookId")) books_dict[bookId] = { "pageId": result.get("id"), - "readingTime": get_property_value(result.get("properties").get("阅读时长")) , - "category": get_property_value(result.get("properties").get("书架分类")) , - "Sort": get_property_value(result.get("properties").get("Sort")) , - "douban_url": get_property_value(result.get("properties").get("豆瓣链接")) , - "cover": get_property_value(result.get("properties").get("封面")) , + "readingTime": get_property_value(result.get("properties").get("阅读时长")), + "category": get_property_value(result.get("properties").get("书架分类")), + "Sort": get_property_value(result.get("properties").get("Sort")), + "douban_url": get_property_value(result.get("properties").get("豆瓣链接")), + "cover": get_property_value(result.get("properties").get("封面")), + "myRating": get_property_value(result.get("properties").get("我的评分")), + "comment": get_property_value(result.get("properties").get("豆瓣短评")), + "status": get_property_value(result.get("properties").get("阅读状态")), } return books_dict - @retry(stop_max_attempt_number=3, wait_fixed=5000) - def query_all_by_book(self,database_id,filter): + def query_all_by_book(self, database_id, filter): results = [] has_more = True start_cursor = None @@ -325,6 +363,7 @@ def query_all_by_book(self,database_id,filter): has_more = response.get("has_more") results.extend(response.get("results")) return results + @retry(stop_max_attempt_number=3, wait_fixed=5000) def query_all(self, database_id): """获取database中所有的数据""" @@ -341,8 +380,8 @@ def query_all(self, database_id): has_more = response.get("has_more") results.extend(response.get("results")) return results - - def get_date_relation(self,properties,date): + + def get_date_relation(self, properties, date): properties["年"] = get_relation( [ self.get_year_relation_id(date), diff --git a/scripts/utils.py b/scripts/utils.py index 39a5e4a2b4f9..66461d8fad6f 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -217,49 +217,48 @@ def get_first_and_last_day_of_week(date): return first_day_of_week, last_day_of_week -def get_properties(dict1, dict2, dict3): +def get_properties(dict1, dict2): properties = {} - for key, value in dict2.items(): - property_type = dict3.get(value) - property_value = dict1.get(key) - if property_value == None: + for key, value in dict1.items(): + type = dict2.get(key) + if value == None: continue property = None - if property_type == TITLE: + if type == TITLE: property = { "title": [ - {"type": "text", "text": {"content": property_value[:MAX_LENGTH]}} + {"type": "text", "text": {"content": value[:MAX_LENGTH]}} ] } - elif property_type == RICH_TEXT: + elif type == RICH_TEXT: property = { "rich_text": [ - {"type": "text", "text": {"content": property_value[:MAX_LENGTH]}} + {"type": "text", "text": {"content": value[:MAX_LENGTH]}} ] } - elif property_type == NUMBER: - property = {"number": property_value} - elif property_type == STATUS: - property = {"status": {"name": property_value}} - elif property_type == FILES: - property = {"files": [{"type": "external", "name": "Cover", "external": {"url": property_value}}]} - elif property_type == DATE: + elif type == NUMBER: + property = {"number": value} + elif type == STATUS: + property = {"status": {"name": value}} + elif type == FILES: + property = {"files": [{"type": "external", "name": "Cover", "external": {"url": value}}]} + elif type == DATE: property = { "date": { "start": pendulum.from_timestamp( - property_value, tz="Asia/Shanghai" + value, tz="Asia/Shanghai" ).to_datetime_string(), "time_zone": "Asia/Shanghai", } } - elif property_type==URL: - property = {"url": property_value} - elif property_type==SELECT: - property = {"select": {"name": property_value}} - elif property_type == RELATION: - property = {"relation": [{"id": id} for id in property_value]} + elif type==URL: + property = {"url": value} + elif type==SELECT: + property = {"select": {"name": value}} + elif type == RELATION: + property = {"relation": [{"id": id} for id in value]} if property: - properties[value] = property + properties[key] = property return properties