diff --git a/api.py b/api.py index 5000a57..a95e840 100644 --- a/api.py +++ b/api.py @@ -83,31 +83,8 @@ class EncryptionHelper: return result.decode() -class ItemManager: - items = {} - - def mapResponseItemsToLocalItems(self, response_items): - for response_item in response_items: - uuid = response_item['uuid'] - - if response_item['deleted']: - if uuid in self.items: - del self.items[uuid] - continue - - self.items[uuid] = response_item - - def getNotes(self): - notes = {} - for key, value in self.items.items(): - if value['content_type'] == 'Note': - note = value['content'] - notes[note['title']] = note['text'] + '\n' - return notes - class StandardNotesAPI: encryption_helper = EncryptionHelper() - item_manager = ItemManager() base_url = 'https://sync.standardnotes.org' sync_token = None @@ -120,30 +97,18 @@ class StandardNotesAPI: res = self.api.post('/auth/sign_in', {'email': self.username, 'password': self.keys['pw']}) self.api.addHeader({'Authorization': 'Bearer ' + res['token']}) - def refreshItems(self): + def sync(self, dirty_items): res = self.api.post('/items/sync', {'sync_token': self.sync_token}) print(json.dumps(res)) + self.sync_token = res['sync_token'] - self.handleResponseItems(res['retrieved_items']) + return self.handleResponseItems(res['retrieved_items']) def handleResponseItems(self, response_items): decrypted_items = self.encryption_helper.pure_decryptResponseItems(response_items, self.keys) - self.item_manager.mapResponseItemsToLocalItems(decrypted_items) - - def getNotes(self): - self.refreshItems() - return self.item_manager.getNotes() + return decrypted_items def __init__(self, username, password): self.api = RESTAPI(self.base_url) self.username = username self.signIn(password) - -if __name__ == "__main__": - notes = StandardNotesAPI('tanner@domain.com', 'complexpass') - - while True: - notes.refreshItems() - print(notes.getNotes()) - - time.sleep(1) diff --git a/itemmanager.py b/itemmanager.py new file mode 100644 index 0000000..b265dff --- /dev/null +++ b/itemmanager.py @@ -0,0 +1,43 @@ +from api import StandardNotesAPI + +class ItemManager: + items = {} + + def mapResponseItemsToLocalItems(self, response_items): + for response_item in response_items: + uuid = response_item['uuid'] + + if response_item['deleted']: + if uuid in self.items: + del self.items[uuid] + continue + + self.items[uuid] = response_item + + def getNotes(self): + notes = {} + sorted_items = sorted(self.items.items(), key=lambda x: x[1]['created_at']) + + for uuid, item in sorted_items: + if item['content_type'] == 'Note': + note = item['content'] + text = note['text'] + '\n' + count = 0 # used to remove title duplicates + + while True: + title = note['title'] + ('' if not count else ' ' + str(count + 1)) + if title in notes: + count += 1 + else: + break + + notes[title] = dict(text=text, + created=item['created_at'], + modified=item['updated_at'], + uuid=item['uuid']) + return notes + + def __init__(self, username, password): + self.standard_notes = StandardNotesAPI(username, password) + response_items = self.standard_notes.sync(None) + self.mapResponseItemsToLocalItems(response_items) diff --git a/sn-fs.py b/sn-fs.py index 1490500..c316c54 100644 --- a/sn-fs.py +++ b/sn-fs.py @@ -1,26 +1,27 @@ from __future__ import print_function, absolute_import, division import errno +import iso8601 import logging import os +import time from stat import S_IFDIR, S_IFREG from sys import argv, exit -from time import time from fuse import FUSE, FuseOSError, Operations, LoggingMixIn -from api import StandardNotesAPI +from itemmanager import ItemManager class StandardNotesFS(LoggingMixIn, Operations): def __init__(self, path='.'): - self.standard_notes = StandardNotesAPI('tanner@domain.com', 'complexpass') - self.notes = self.standard_notes.getNotes() + self.item_manager = ItemManager('tanner@domain.com', 'complexpass') + self.notes = self.item_manager.getNotes() self.uid = os.getuid() self.gid = os.getgid() - now = time() + now = time.time() self.dir_stat = dict(st_mode=(S_IFDIR | 0o755), st_ctime=now, st_mtime=now, st_atime=now, st_nlink=2, st_uid=self.uid, st_gid=self.gid) @@ -38,7 +39,10 @@ class StandardNotesFS(LoggingMixIn, Operations): if path == '/': return self.dir_stat elif note_name in self.notes: - st['st_size'] = len(self.notes[note_name]) + note = self.notes[note_name] + st['st_size'] = len(note['text']) + st['st_ctime'] = iso8601.parse_date(note['created']).timestamp() + st['st_mtime'] = iso8601.parse_date(note['modified']).timestamp() return st else: raise FuseOSError(errno.ENOENT) @@ -53,8 +57,9 @@ class StandardNotesFS(LoggingMixIn, Operations): def read(self, path, size, offset, fh): path_parts = path.split('/') note_name = path_parts[1] + note = self.notes[note_name] - return self.notes[note_name][offset : offset + size].encode() + return note['text'][offset : offset + size].encode() def chmod(self, path, mode): return 0