import subprocess import json import time notebook_id = "e8a30630-0df2-4932-8740-9ffe7d8882bc" nlm_bin = "/opt/ai-os/products/ceo/integrations/notebooklm-mcp-cli/.venv/bin/nlm" gapi_bin = "/root/.hermes/profiles/khoi/skills/productivity/google-workspace/scripts/google_api.py" # Step 1: Get current sources in Notebook r = subprocess.run([nlm_bin, "source", "list", notebook_id, "--json"], capture_output=True, text=True) current_sources = json.loads(r.stdout) print(f"Total current sources: {len(current_sources)}") # Step 2: Identify sources to DELETE (short duplicate names like PR, Ch.10.pdf, PR, Ch.6.pdf, etc.) # and duplicate SAB files to_delete = [] for s in current_sources: t = s['title'] sid = s['id'] # If title is in the format 'PR, Ch.X.pdf' (without descriptive name) # or duplicate GM, Ch.1- 10 Ly Thuyet Kinh Te Hoc.pdf if any(t == f"PR, Ch.{i}.pdf" for i in range(1, 20)): to_delete.append((sid, t)) elif t == "GM, Ch.1- 10 Ly Thuyet Kinh Te Hoc.pdf": to_delete.append((sid, t)) print(f"Sources to delete (duplicates/stale): {len(to_delete)}") for sid, t in to_delete: print(f" Deleting: {t} ({sid})") subprocess.run([nlm_bin, "source", "delete", notebook_id, sid], capture_output=True) time.sleep(0.5) # Step 3: Refresh source list r = subprocess.run([nlm_bin, "source", "list", notebook_id, "--json"], capture_output=True, text=True) current_sources = json.loads(r.stdout) print(f"Sources remaining: {len(current_sources)}") # Step 4: Rename existing sources to comply with convention # [G] for general guides # [DDMM] for session reading files rename_map = { "1. So Tay Hoc Vien MPP28 - digital.pdf": "[G]_1. So Tay Hoc Vien MPP28 - digital.pdf", "2.1. Library_Rules_Copying_Guidelines_(ENG).pdf": "[G]_2.1. Library_Rules_Copying_Guidelines_(ENG).pdf", "2.2. Instructions_for_Searching_and_Using_Online_Databases_(ENG).pdf": "[G]_2.2. Instructions_for_Searching_and_Using_Online_Databases_(ENG).pdf", "2.3. List_of_Online_Databases_(ENG).pdf": "[G]_2.3. List_of_Online_Databases_(ENG).pdf", "2.4. HuongDanTrichDanTLTK_MPP2028.pdf": "[G]_2.4. HuongDanTrichDanTLTK_MPP2028.pdf", "MPP2028-PA-Syllabus-Micro1.pdf": "[G]_01. MPP2028-PA-Syllabus-Micro1.pdf", "[G]_01. MPP2028-PA-Syllabus-Micro1.pdf": "[G]_01. MPP2028-PA-Syllabus-Micro1.pdf", # 03.11 "[0311] SAB, Ch. 1 - Micro For Public Decisions Overview.pdf": "[0311] SAB, Ch. 1 - Micro For Public Decisions Overview.pdf", "[0311] SAB, Ch. 1 - Giới thiệu Kinh tế học vi mô và Chính sách công": "[0311] SAB, Ch. 1 - Giới thiệu Kinh tế học vi mô và Chính sách công", # 10.11 "GM, Ch. 1 - Mười nguyên lý của kinh tế học.pdf": "[1011] GM, Ch. 1 - Mười nguyên lý của kinh tế học.pdf", # 15.11 "PR, Ch. 3 - Hành vi của người tiêu dùng.pdf": "[1511] PR, Ch. 3 - Hành vi của người tiêu dùng.pdf", # 16.11 "PR, Ch. 6 - Sản xuất.pdf": "[1611] PR, Ch. 6 - Sản xuất.pdf", "PR, Ch. 7 - Chi phí sản xuất.pdf": "[1611] PR, Ch. 7 - Chi phí sản xuất.pdf", # 17.11 "PR, Ch. 8 - Tối đa hóa lợi nhuận và cung cạnh tranh.pdf": "[1711] PR, Ch. 8 - Tối đa hóa lợi nhuận và cung cạnh tranh.pdf", "PR, Ch. 9 - Phân tích thị trường cạnh tranh.pdf": "[1711] PR, Ch. 9 - Phân tích thị trường cạnh tranh.pdf", "[1711] SAB, Ch. 7 - Phân tích thị trường": "[1711] SAB, Ch. 7 - Phân tích thị trường", # 18.11 "Ariely, Ch. 7 - Cái giá của sự sở hữu.pdf": "[1811] Ariely, Ch. 7 - Cái giá của sự sở hữu.pdf", "Ariely, Ch. 9 - Hiệu ứng của sự mong đợi.pdf": "[1811] Ariely, Ch. 9 - Hiệu ứng của sự mong đợi.pdf", "Thaler, Ch. 1 - Những yếu tố được cho là không phù hợp.pdf": "[1811] Thaler, Ch. 1 - Những yếu tố được cho là không phù hợp.pdf", "Thaler, Ch. 2 - Hiệu ứng quyền sở hữu.pdf": "[1811] Thaler, Ch. 2 - Hiệu ứng quyền sở hữu.pdf", "Thaler, Ch. 4 - Lý thuyết giá trị.pdf": "[1811] Thaler, Ch. 4 - Lý thuyết giá trị.pdf", "Thaler, Ch. 7 - Giá hời và giá hớ.pdf": "[1811] Thaler, Ch. 7 - Giá hời và giá hớ.pdf", "Thaler, Ch. 8 - Chi phí chìm.pdf": "[1811] Thaler, Ch. 8 - Chi phí chìm.pdf", "Thaler, Ch. 15 - Các trò chơi công bằng.pdf": "[1811] Thaler, Ch. 15 - Các trò chơi công bằng.pdf", "Thaler, Ch. 31 - Ngày mai tiết kiệm nhiều hơn.pdf": "[1811] Thaler, Ch. 31 - Ngày mai tiết kiệm nhiều hơn.pdf", "Thaler, Ch. 33 - Cú hích tại Anh.pdf": "[1811] Thaler, Ch. 33 - Cú hích tại Anh.pdf", # 19.11 "[1911] SAB, Ch. 6 - Hiệu quả và công bằng": "[1911] SAB, Ch. 6 - Hiệu quả và công bằng", "PR, Ch. 16 - Cân bằng tổng thể và hiệu quả kinh tế.pdf": "[1911] PR, Ch. 16 - Cân bằng tổng thể và hiệu quả kinh tế.pdf", # 20.11 "PR, Ch. 10 - Sức mạnh thị trường (Độc quyền bán và mua).pdf": "[2011] PR, Ch. 10 - Sức mạnh thị trường (Độc quyền bán và mua).pdf", "PR, Ch. 12 - Cạnh tranh độc quyền và độc quyền nhóm.pdf": "[2011] PR, Ch. 12 - Cạnh tranh độc quyền và độc quyền nhóm.pdf", # 28.11 "PR, Ch. 17 - Thị trường với thông tin bất đối xứng.pdf": "[2811] PR, Ch. 17 - Thị trường với thông tin bất đối xứng.pdf", # 29.11 "PR, Ch. 18 - Ngoại tác và hàng hóa công cộng.pdf": "[2911] PR, Ch. 18 - Ngoại tác và hàng hóa công cộng.pdf", "[2911] SAB, Ch. 9 - Ngoại tác": "[2911] SAB, Ch. 9 - Ngoại tác", "[2911] SAB, Ch. 10 - Hàng hóa công cộng": "[2911] SAB, Ch. 10 - Hàng hóa công cộng", } for s in current_sources: t = s['title'] sid = s['id'] if t in rename_map and rename_map[t] != t: new_name = rename_map[t] print(f"Renaming: '{t}' -> '{new_name}'") subprocess.run([nlm_bin, "source", "rename", "--notebook", notebook_id, sid, new_name], capture_output=True) time.sleep(0.3) # Step 5: Check missing Drive files that need to be added # 1. 26.11.14: PR, Ch. 2 - Những nguyên lý cơ bản của cung và cầu.pdf (1YKCEvwCt1DKuib3am9ED1suNZVvZ66iD) # 2. 26.11.25: PR, Ch. 11 - Định giá khi có sức mạnh thị trường.pdf (1APSJjS8PQ471Cprd4Arc7k8MdyjJc9VF) missing_to_add = [ ("1YKCEvwCt1DKuib3am9ED1suNZVvZ66iD", "[1411] PR, Ch. 2 - Những nguyên lý cơ bản của cung và cầu.pdf", "pdf"), ("1APSJjS8PQ471Cprd4Arc7k8MdyjJc9VF", "[2511] PR, Ch. 11 - Định giá khi có sức mạnh thị trường.pdf", "pdf"), ] for fid, title, ftype in missing_to_add: print(f"Adding missing source: {title} ({fid})...") res = subprocess.run([nlm_bin, "source", "add", notebook_id, "--drive", fid, "--title", title, "--type", ftype], capture_output=True, text=True) if res.returncode == 0: print(f" ✓ Added: {title}") else: print(f" ✗ Failed: {res.stderr.strip()}") time.sleep(0.5) print("\nFinished cleaning and standardizing!")