Skip to content

Instantly share code, notes, and snippets.

@skarfie123
Created February 2, 2024 23:21
Show Gist options
  • Select an option

  • Save skarfie123/a69352a46bcf80d7ad48e0dc37f794e1 to your computer and use it in GitHub Desktop.

Select an option

Save skarfie123/a69352a46bcf80d7ad48e0dc37f794e1 to your computer and use it in GitHub Desktop.

Revisions

  1. skarfie123 created this gist Feb 2, 2024.
    161 changes: 161 additions & 0 deletions workona_to_bookmarks.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,161 @@
    import typer
    from pydantic import BaseModel, ConfigDict, Field


    class NoExtrasModel(BaseModel):
    model_config = ConfigDict(extra="forbid")


    class User(NoExtrasModel):
    name: str
    id: str
    lastActive: int
    email: str
    domain: str
    lastName: str
    avatar: str
    firstName: str
    updatedAt: int
    createdAt: int


    class Tab(NoExtrasModel):
    title: str
    url: str


    class Resource(Tab):
    description: str | None = None


    class ResourceSection(NoExtrasModel):
    title: str
    resources: list[Resource]


    class Note(NoExtrasModel):
    title: str
    description: str | None
    attachments: list


    class NoteSection(NoExtrasModel):
    title: str
    notes: list[Note]


    class Task(BaseModel):
    pass


    class TaskSection(NoExtrasModel):
    title: str
    tasks: list[Task]


    class BaseWorkspace(NoExtrasModel):
    title: str
    tabs: list[Tab]
    resources: list[ResourceSection]
    notes: list[NoteSection]
    tasks: list[TaskSection]


    class Workspace(BaseWorkspace):
    color: str


    class WorkspaceGroup(NoExtrasModel):
    title: str
    workspaces: list[Workspace]


    class ArchivedWorkspace(BaseWorkspace):
    pass


    class MyTasks(NoExtrasModel):
    today: list[Task] = Field(..., alias="Today")
    soon: list[Task] = Field(..., alias="Soon")


    class Workona(NoExtrasModel):
    user: User = Field(..., alias="User")
    workspaces: list[WorkspaceGroup] = Field(..., alias="Workspaces")
    archived_workspaces: list[ArchivedWorkspace] = Field(
    ..., alias="Archived Workspaces"
    )
    my_tasks: MyTasks = Field(..., alias="My Tasks")


    def workona_to_bookmarks(workona: Workona) -> str:
    """
    Convert parsed workona data into bookmarks file.
    Bookmarks file uses NETSCAPE-Bookmark-file-1 format.
    """
    bookmarks = """<!DOCTYPE NETSCAPE-Bookmark-file-1>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
    <TITLE>Bookmarks</TITLE>
    <H1>Bookmarks</H1>
    <DL><p>
    <DT><H3>Workona</H3>
    <DL><p>"""

    for workspace_group in workona.workspaces:
    bookmarks += f"""
    <DT><H3>{workspace_group.title}</H3>
    <DL><p>"""

    for workspace in workspace_group.workspaces:
    if not workspace.tabs:
    continue

    bookmarks += f"""
    <DT><H3>{workspace.title}</H3>
    <DL><p>"""

    for tab in workspace.tabs:
    bookmarks += f"""
    <DT><A HREF="{tab.url}">{tab.title}</A>"""

    for resource_section in workspace.resources:
    if not resource_section.resources:
    continue
    bookmarks += f"""
    <DT><H3>{resource_section.title}</H3>
    <DL><p>"""
    for resource in resource_section.resources:
    bookmarks += f"""
    <DT><A HREF="{resource.url}">{resource.title}</A>"""

    bookmarks += """
    </DL><p>"""

    bookmarks += """
    </DL><p>"""

    bookmarks += """
    </DL><p>"""

    bookmarks += """
    </DL><p>
    </DL><p>"""

    return bookmarks


    def main(export_file: str):
    with open(export_file, "r", encoding="utf-8") as f:
    data = f.read()

    workona = Workona.model_validate_json(data, strict=True)

    bookmarks = workona_to_bookmarks(workona)

    with open("workona.html", "w", encoding="utf-8") as f:
    f.write(bookmarks)


    if __name__ == "__main__":
    typer.run(main)