Git Product home page Git Product logo

trilium-py's Introduction

🐍 trilium-py

English | 简体中文

Python client for ETAPI of Trilium Note.

Downloads Supported Versions Supported Versions PyPI license Maintenance


🦮 Table of Contents

🔧 Installation

python3 -m pip install trilium-py --user

📖 (Basic) Usage

These are basic function that Trilium's ETAPI provides. Down below are some simple example code to use this package.

🚀 Initialization

If you have a ETAPI token, change the server_url and token to yours.

from trilium_py.client import ETAPI

server_url = 'http://localhost:8080'
token = 'YOUR_TOKEN'
ea = ETAPI(server_url, token)

If you haven't created ETAPI token, you can create one with your password. Please note, you can only see this token once, please save it if you want to reuse the token.

from trilium_py.client import ETAPI

server_url = 'http://localhost:8080'
password = '1234'
ea = ETAPI(server_url)
token = ea.login(password)
print(token)

After initialization, you can use Trilium ETAPI with python now. The following are some examples.

📊 Application Information

To start with, you can get the application information like this.

print(ea.app_info())

It should give you the version of your server application and some extra information.

🔍 Search note

Search note with keyword.

res = ea.search_note(
    search="python",
)

for x in res['results']:
    print(x['noteId'], x['title'])

Search with regular expression. For example, search and get all child notes under certain note:

res = ea.search_note(
    # regular expression search for note title
    search="note.title %= '.*'",
    ancestorNoteId="Parent Note ID",
    fastSearch=False,
    limit=1000,
)

🏭 Create Note

You can create a simple note like this.

res = ea.create_note(
    parentNoteId="root",
    title="Simple note 1",
    type="text",
    content="Simple note example",
    noteId="note1"
)

The noteId is not mandatory, if not provided, Trilium will generate a random one. You can retrieve it in the return.

noteId = res['note']['noteId']

🖼️ Create Image note

Image note is a special kind of note. You can create an image note with minimal information like this. The image_file refers to the path of image.

res = ea.create_image_note(
    parentNoteId="root",
    title="Image note 1",
    image_file="shield.png",
)

👀 Get note

To retrieve the note's content.

ea.get_note_content("noteid")

You can get a note metadata by its id.

ea.get_note(note_id)

🔄 Update note

Update note content

ea.update_note_content("noteid", "updated by python")

Modify note title

ea.patch_note(
    noteId="noteid",
    title="Python client moded",
)

🗑️ Delete note

Simply delete a note by id.

ea.delete_note("noteid")

📅 Day note

You can get the content of a certain date with get_day_note. The date string should be in format of "%Y-%m-%d", e.g. " 2022-02-25".

ea.get_day_note("2022-02-25")

Then set/update a day note with set_day_note. The content should be a (html) string.

ea.set_day_note(date, new_content)

📤 Export note

Export note comes in two formats html or markdown/md.

res = ea.export_note(
    noteId='sK5fn4T6yZRI',
    format='md',
    savePath='/home/nate/data/1/test.zip',
)

💾 Create data backup

This example will create a database backup file like this trilium-data/backup/backup-test.db.

res = ea.backup("test")

You can use the cron utility in Linux to schedule regular automatic backups. For example, to set up a daily backup at 3: 00 AM, you would use the following cron expression:

0 3 * * * python /path/to/backup-script.py

🏷 Create attribute

You can create a tag for a note

res = ea.create_attribute(
    noteId='noteid',
    type='label',
    name='name_of_the_tag',
    value='value_of_the_tag',
    isInheritable=True
)

The noteId is not mandatory, if not provided, Trilium will generate a random one. You can retrieve it in the return.

noteId = res['note']['noteId']

Get attachment info

Get image title and etc.

res = ea.get_attachment('Y5V6pYq6nwXo')

Update attachment info

Change image title and etc.

res = ea.update_attachment(
    attachmentId='2b7pPzqocS1s', title='hello etapi', role='image', mime='image/png'
)

Get attachment content

Get the real image file

res = ea.get_attachment_content('icpDE4orQxlI')
with open('1.png', 'wb') as f:
    f.write(res)

Update attachment content

Replace the image with new one

res = ea.update_attachment_content('icWqV6zFtE0V', '/home/nate/data/1.png')

Create attachment

Upload a image file as attachment of a note.

res = ea.create_attachment(
    ownerId='8m8luXym5LxT',
    file_path='/home/nate/data/ksnip_20230630-103509.png',
)

(Advanced Usage) ✅ TODO List

With the power of Python, I have expanded the basic usage of ETAPI. You can do something with todo list now.

Add TODO item

You can use add_todo to add a TODO item, param is the TODO description

ea.add_todo("买暖宝宝")

Check/Uncheck a TODO item

param is the index of the TODO item

ea.todo_check(0)
ea.todo_uncheck(1)

Update a TODO item

Use update_todo to update a TODO item description at certain index.

ea.update_todo(0, "去码头整点薯条")

Delete a TODO item

Remove a TODO item by its index.

ea.delete_todo(1)

Move yesterday's unfinished todo to today

As the title suggests, you can move yesterday's unfinished things to today. Unfinished todo's will be deleted from yesterday's note.

ea.move_yesterday_unfinished_todo_to_today()

(Advanced Usage) 🚚 Upload Markdown files

Upload single Markdown file with images

You can import Markdown file with images into Trilium now! Trilium-py will help you to upload the images and fix the links for you!

res = ea.upload_md_file(
    parentNoteId="root",
    file="./md-demo/manjaro 修改caps lock.md",
)

Bulk upload Markdown files in a folder

You can upload a folder with lots of Markdown files to Trilium and preserve the folder structure!

Import from VNote

Say, upload all the notes from VNote, simply do this:

res = ea.upload_md_folder(
    parentNoteId="root",
    mdFolder="~/data/vnotebook/",
    ignoreFolder=['vx_notebook', 'vx_recycle_bin', 'vx_images', '_v_images'],
)

Import from Joplin

Joplin can be imported effortlessly.

res = ea.upload_md_folder(
    parentNoteId="root",
    mdFolder="/home/nate/data/joplin_data/",
    ignoreFolder=['_resources', ],
)

Import from Logseq

res = ea.upload_md_folder(
    parentNoteId="root",
    mdFolder="/home/nate/data/logseq_data/",
    ignoreFolder=['assets', 'logseq'],
)

Import from Obsidian

Obsidian has a very unique linking system for files. You should use obsidian-export to convert a Obsidian vault to regular Markdown files. Then you should be able to import the note into Trilium with trilium-py.

Convert it first.

obsidian-export /path/to/your/vault /out

Then import just like a normal markdown, trilium-py will handle the images for you.

res = ea.upload_md_folder(
    parentNoteId="root",
    mdFolder="E:/data/out",
)

Import from Youdao Note/有道云笔记

Youdao does not provide an export feature anymore. Luckily, you can use https://github.com/DeppWang/youdaonote-pull to download your notes and convert them into markdown files. After that, trilium-py should be able to help you import them.

res = ea.upload_md_folder(
    parentNoteId="root",
    mdFolder="/home/nate/gitRepo/youdaonote-pull/out/",
)

Import from Turtl

You need to convert Turtl from json to markdown first. See turtl-to-markdown for details.

Then you can import with trilium-py like this:

res = ea.upload_md_folder(
    parentNoteId="root",
    mdFolder="/home/nate/gitRepo/turtl-to-markdown/out/",
    ignoreFolder=['_resources'],
)

Import from other markdown software

In general, markdown files have variety of standards. You can always try import them with

res = ea.upload_md_folder(
    parentNoteId="root",
    mdFolder="/home/nate/data/your_markdown_files/",
)

If there is any problem, please feel free to create an issue.

(Advanced Usage) 🎨 Beautify notes

Because of the constraints imposed by the library utilized by Trilium, imported notes may experience minor formatting problems. These issues include an additional line appearing at the end of code blocks, images becoming integrated with the note content, and the absence of line breaks between headings, resulting in a cramped appearance of the note content.

Here is what you can do to beautify your note.

Beautify a note

Specify a note id to beautify note content.

ea.beautify_note('krm8B9JthNfi')

Beautify a note and its child notes

ea.beautify_sub_notes('tlPuzU2szLJh')

(Advanced Usage) 🧹 Sort note content

Sort a note by the heading names. This feature could prove invaluable for notes containing extensive lists, such as book titles sorted into various genres. It's equally useful for managing browser bookmarks or collecting links.

Additionally, you have the option to specify a language code for sorting based on your local language. This enhances the sorting process and tailors it to your linguistic preferences.

res = ea.sort_note_content('lPxtkknjR2bJ')
res = ea.sort_note_content('y6hROhWjNmHQ', 'zh_CN.UTF-8')

🛠️ Develop

Install with pip egg link to make package change without reinstall.

python -m pip install --user -e .

🔗 Original OpenAPI Documentation

The original OpenAPI document is here. You can open it with swagger editor.

trilium-py's People

Contributors

alrhalford avatar egutierrez-ar avatar foozzi avatar jwhonce avatar lndldufer avatar nriver avatar perfectra1n avatar rhilip avatar unfortunatelyalex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

trilium-py's Issues

Sync by using trilium-py?

I don't find the proper API method for syncing.

I may need to get notes after specific modifiedDate.

em tags in imported image paths

Hello,

trilium-py has been invaluable. Thank you for all your work.

I am using trilium-py version 0.8.2.

After importing an obsidian vault using obsidian-export and importing it using upload_md_folder, I ended up with a series of images that had the underscores replaced with em tags. For example: 2023_abandoned_canyon.png becomes 2023<em>abandoned</em>canyon.png.

Below is a simple python script to fix entries that have been corrupted in that way that worked for me™️ and provides a workaround for the issue.

res = ea.search_note("</em>")
for r in res['results']:
    if r["type"] == "image" and "</em>" in r['title']:
        orig_title = r['title']
        new_title = orig_title.replace("<em>", "_").replace("</em>", "_")
        ea.patch_note(r['noteId'], title=new_title)
        print(f" [!] {orig_title} -> {new_title}")

        for n in r['parentNoteIds']:
            id = n
            n = ea.get_note(id)
            print(f" [ ] - {n['title']}")
            c = ea.get_note_content(id)
    
            c = c.replace(orig_title, new_title)
            ea.update_note_content(id, c)
        
        print(" [-] Fixed")

Problem with certain images when importing .md

There are certain images that are not recognized correctly when importing markdown files.

<p><img width="736" height="414" src="../certainpath.jpg"/></p>

that is due to the fact that the regex expression in

pat = '<img (.*?) />'
is expecting a white space just before "/>". And that is not always the case (even with though all the code is generated by markdown2markdown.

the simplest solution is to change that line to:

pat = '<img (.*?)/>'
But i'm not sure that that change could generate problems with other images (not that i can think of)

Duplicate Journal Day Note

I am not sure this is a trilium-py or trilium sync server issue. Or, mine...

I wrote a script to query critical items from Jira and create TODO items for me on the Journal Day Note. The script works fine when the Day note exists.

When it creates a new empty page (3am via cron) and then I press the "Open Today's Journal Note" launcher (at 8am) the launcher creates a second note for the day... The note created by trilium-py has the TODO items and my Day template contents while the launcher note only has my "Day template" contents.

I am running a sync server (quadlet/podman) and the script is configured to run against that server. The launcher, of course, is run on my laptop.

Is it "bad" style to call the ETAPI endpoint refresh-note-ordering after creating the Day note? That is the only ETAPI endpoint that seems to push to clients. At least from the OpenAPI spec. Or, there appears to be apiRoute(POST, '/api/sync/now'

Homepage: https://github.com/zadam/trilium
App version: 0.60.4
DB version: 214
Sync version: 29
Build date: 2023-06-19T23:26:50+02:00
Build revision: 5905950c17791ce0eb278e010c2c8b3450fdb447
Data directory: .../.local/share/trilium-data
Image: docker.io/zadam/trilium:0.60.4

ModuleNotFoundError: No module named 'magic'

Running this package from pypi results in the error: ModuleNotFoundError: No module named 'magic'

It looks like there may have been a pull request that fixed this. Maybe you only need to re-deploy to pypi?

Import markdown files with frontmatter yaml?

Thanks for creating this library! I've only just started testing out Trilium, but I'm liking it so far. One of the things I'd like to do is import all of my old notes from Joplin and Obsidian.

I used a script similar to the one in the README but noticed yaml frontmatter doesn't get preserved. For example, a joplin exported note like this:

---
title: 2021-03-05 - hvac furnace tune up
updated: 2021-03-05 15:27:20Z
created: 2021-03-05 13:43:07Z
latitude: xx.xx
longitude: -yy.yy
altitude: 101
---

note contents here

Gets turned into this (when viewing the source of the trilium note):

<hr />

<p>title: 2021-03-05 - hvac furnace tune up
updated: 2021-03-05 15:27:20Z
created: 2021-03-05 13:43:07Z
latitude: xx.xx
longitude: -yy.yy</p>

<h2>altitude: 101</h2>

<p>note contents here</p>

Is it possible (and does it make sense) to convert that yaml frontmatter and turn it into attributes on the note? For my example, I think it'd get turned into something like #latitude=xx.xx #longitude=-yy.yy #altitude=101 .

I've used https://pypi.org/project/python-frontmatter/ in the past and it worked okay. I haven't looked much at the code here or the trilium api, but I might try to take a look this weekend if I continue w/ trilium.

Img tags without closing "/>"

Hi,

again with importing img tags. I'm still importing some md files and i found another issue (previous: #34) related with the regex expression. I still found some images that are not properly imported. That's because img tag not necessarily need a closing match /> and > is enough. This can be seen in the example from the w3schools

<img src="img_girl.jpg" alt="Girl in a jacket" width="500" height="600">

So, again, probably the regex expression should be better like this:

pat = '<img (.*?)/?>'

So the / is optional.

Error raised using code from main: 4dc017d03d65dad31871e36b6d1fd59439d80b34

Traceback (most recent call last):
  File "/home/jhonce/Projects/trilium-addons/bugSLA/bugSLA.py", line 25, in <module>
    from trilium_py.client import ETAPI
  File "/home/jhonce/Projects/Python/trilium-py/src/trilium_py/client.py", line 18, in <module>
    from .utils.note_util import beautify_content, sort_note_by_headings
  File "/home/jhonce/Projects/Python/trilium-py/src/trilium_py/utils/note_util.py", line 7, in <module>
    from trilium_py.src.trilium_py.utils.html_util import sort_h_tags_with_hierarchy
ModuleNotFoundError: No module named 'trilium_py.src'

Using python 3.11 and trilium-py installed using python -m pip install --user -e .

[feature requests] Upload file

Sounds like markdown import only process image, sometime the markdown file contain link to other file, which not upload in this script.

Could I use this for making ChatGPT bot?

I want to use ChatGPT API for updating notes by clicking a button or pushing hotkeys in a note.

Can this library be used for my purpose?

I am proficient in Python but have no idea about Node.js things.

Thanks.

Question: What is the earliest python version to be supported?

I have been working from the assumption that you intended to support Python 3.6+ is that true? You mentioned in another issue that the project was using default templates. If the project drops earlier versions that will clean up some of the typing code.

I would like to configure tox and add unit tests.

/jwh

    classifiers=[  # Optional
        # How mature is this project? Common values are
        #   3 - Alpha
        #   4 - Beta
        #   5 - Production/Stable
        'Development Status :: 5 - Production/Stable',

        # Indicate who your project is intended for
        'Intended Audience :: Developers',
        'Topic :: Software Development :: Build Tools',

        # Pick your license as you wish
        'License :: OSI Approved :: GNU Affero General Public License v3',

        # Specify the Python versions you support here. In particular, ensure
        # that you indicate you support Python 3. These classifiers are *not*
        # checked by 'pip install'. See instead 'python_requires' below.
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3.9',
        "Programming Language :: Python :: 3.10",
        "Programming Language :: Python :: 3.11",
        'Programming Language :: Python :: 3 :: Only',
    ],

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.