kiwiz / gkeepapi

An unofficial client for the Google Keep API.
MIT License
1.54k stars 114 forks source link

How to export notes local system? #135

Closed chaoscreater closed 1 year ago

chaoscreater commented 1 year ago

I've checked the documentation and it doesn't seem to have a native function for exporting notes to Windows.

I'm not a programmer and barely know Python, but I managed to write something like this (with the help of ChatGPT):

`notes = keep.all()

for note in notes:

print(note.title)

# print(note.text)

# Create a file with the note title if it does not exist inside the "Google Keep Notes backup" folder
backup_folder = 'Google Keep Notes backup'
if not os.path.exists(backup_folder):
    os.makedirs(backup_folder)

filename = os.path.join(backup_folder, note.title + '.txt')
if not os.path.exists(filename):
    open(filename, 'w').close()

# Append the note text to the file
with open(filename, 'a') as file:
    file.write(note.text)

While that worked for most notes, it fails when there's a checkbox found in the notes.

Traceback (most recent call last):
  File "C:\Users\BlahUserName\gkeepapi\Test.py", line 42, in <module>
    file.write(note.text)
  File "C:\Users\Ricky\AppData\Local\Programs\Python\Python39-32\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2610' in position 0: character maps to <undefined>

\u2610 is the unicode character for checkbox and I've seen this error in other Google Keep Github projects. It seems I can't find any that can properly export the notes to my PC. I just want to backup my notes on a scheduled basis....

kiwiz commented 1 year ago

You can resolve this by opening the file in utf-8 mode: open(filename, 'a', encoding='utf-8')

I'll also plug keep-cli, which has a command to export to markdown: https://github.com/kiwiz/keep-cli

$ keep export
chaoscreater commented 1 year ago

Thanks, that worked.

I've looked at keep-cli and while I can login to Google Keep successfully, it has a few issues and I'm guessing that it's because it hasn't been updated since 2020. I've posted the issue here: https://github.com/kiwiz/keep-cli/issues/9

I do have another issue and I'm wondering if you could help me here? Some of my notes have special symbol characters, for example: "Control Panel upgrade / script" and that is causing issues when the note gets exported out:

Traceback (most recent call last):
  File "C:\Users\Ricky\gkeepapi\1. RunMe.py", line 39, in <module>
    open(filename, 'w').close()
FileNotFoundError: [Errno 2] No such file or directory: 'Google Keep Notes backup\\Control Panel upgrade / script.txt'

I think the reason is because you can't actually create a file with special characters in Windows.

The other problem is that some of my Keep notes do not have a title. In that case, I think I'll need to check if the note title is empty or not and if yes, then create a file with the current looped index or something?

I'm too dumb to figure this out and programming isn't my cup of tea. Would appreciate it if you could help me out here.

kiwiz commented 1 year ago

Your theory is correct. You can get around this by escaping the characters that are invalid. For example, urllib.parse.quote(note.title). Separately, if the note doesn't have a title you can sub in the ID: note.id

chaoscreater commented 1 year ago

hmm I ended up using ChatGPT to do this for me. I think it works OK.

Sharing it for the next person to use:

import gkeepapi
import shutil
import os
import re

keep = gkeepapi.Keep()
success = keep.login('username@gmail.com', 'your_password_here')

'''
note = keep.createNote('Todo', 'Eat breakfast')
note.pinned = True
note.color = gkeepapi.node.ColorValue.Red
keep.sync()

# Create a file with the note title if it does not exist
filename = note.title + '.txt'
if not os.path.exists(filename):
    open(filename, 'w').close()

# Append the note text to the file
with open(filename, 'a') as file:
    file.write(note.text)

'''

notes = keep.all()

backup_folder = 'Google Keep Notes backup'

if os.path.exists(backup_folder):
    shutil.rmtree(backup_folder)

for i, note in enumerate(notes):
    # print(note.title)
    # print(note.text)

    # Remove special characters from note titles
    if note.title:
        note_title = re.sub('[^A-Za-z0-9 ]+', '', note.title)
    else:
        note_title = str(i)

    print(note_title)

    # Create a file with the note title if it does not exist inside the "Google Keep Notes backup" folder

    if not os.path.exists(backup_folder):
        os.makedirs(backup_folder)

    if note.title is None or len(note.title.strip()) == 0:
        filename = os.path.join(backup_folder, str(i) + '.txt')
    else:
        filename = os.path.join(backup_folder, note_title + '.txt')

    if not os.path.exists(filename):
        open(filename, 'w').close()

    # Append the note text to the file
    # with open(filename, 'a', encoding='utf-8') as file:

    # Write the note text to the file
    with open(filename, 'w', encoding='utf-8') as file:
        file.write(note.text)
kiwiz commented 1 year ago

Looks pretty reasonable! I'm going to close this out since you've got a solution.