Example #1
0
class ENNoteObj:
    """ wrap NoteMetadata object (evernote.edam.notestore.ttypes.NoteMetadata) for mongo sync """
    def __init__(self, note, sleep_on_ratelimit):
        self.sleep_on_ratelimit = sleep_on_ratelimit
        self._note = note
        self._note.content = None

    def load_tags(self):
        self.gn = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit)
        self.gn.loadNoteTags(self._note)

    def load_content(self):
        self.gn = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit)
        self.gn.loadNoteContent(self._note)

    def get_image_resource(self, imageInfo):
        guid = self._note.guid
        binary_hash = binascii.unhexlify(imageInfo['hash'])
        try:
            resource = self.gn.handleMedia(guid, binary_hash, lambda r: r)
        except Exception as err:
            # EDAMNotFoundException - what else?
            logger.error('failed to lookup image for %s  - %s', imageInfo, err)
            return None
        return resource

    def __getattr__(self, name):
        notfound = object()
        value = getattr(self._note, name, notfound)
        if value is notfound:
            raise AttributeError(name)
        return value
Example #2
0
    def _get_notebook(self, notebook_name):
        """
        Get notebook guid and name.
        Takes default notebook if notebook's name does not select.
        """
        notebooks = GeekNote(
            sleepOnRateLimit=self.sleep_on_ratelimit).findNotebooks()
        assert notebook_name
        notebook_name = notebook_name.lower(
        )  # avoid troubles with case-sensitivity

        notebook = [
            item for item in notebooks if item.name.lower() == notebook_name
        ]
        guid = None
        if notebook:
            guid = notebook[0].guid
        else:
            logger.warning("missing notebook %s", notebook_name)

        if not guid:
            notebook = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit
                                ).createNotebook(notebook_name)

            if (notebook):
                logger.info('Notebook "{0}" was'
                            ' created'.format(notebook_name))
            else:
                raise Exception('Notebook "{0}" was'
                                ' not created'.format(notebook_name))

            guid = notebook.guid

        return (guid, notebook_name)
Example #3
0
    def _create_file(self, note):
        """
        Creates file from note
        """
        GeekNote().loadNoteContent(note)

        # Save images
        if 'saveImages' in self.imageOptions and self.imageOptions['saveImages']:
            imageList = Editor.getImages(note.content)
            if imageList:
                if 'imagesInSubdir' in self.imageOptions and self.imageOptions['imagesInSubdir']:
                    os.mkdir(os.path.join(self.path, note.title + "_images"))
                    imagePath = os.path.join(self.path, note.title + "_images", note.title)
                    self.imageOptions['baseFilename'] = note.title + "_images/" + note.title
                else:
                    imagePath = os.path.join(self.path, note.title)
                    self.imageOptions['baseFilename'] = note.title
                for imageInfo in imageList:
                    filename = "{}-{}.{}".format(imagePath, imageInfo['hash'], imageInfo['extension'])
                    logger.info('Saving image to {}'.format(filename))
                    binaryHash = binascii.unhexlify(imageInfo['hash'])
                    GeekNote().saveMedia(note.guid, binaryHash, filename)

        content = Editor.ENMLtoText(note.content, self.imageOptions)
        path = os.path.join(self.path, note.title + self.extension)
        open(path, "w").write(content)
        os.utime(path, (-1, note.updated / 1000))

        return True
Example #4
0
    def _get_notebook(self, notebook_name, path):
        """
        Get notebook guid and name.
        Takes default notebook if notebook's name does not select.
        """
        notebooks = GeekNote().findNotebooks()

        if not notebook_name:
            notebook_name = os.path.basename(os.path.realpath(path))

        notebook = [item for item in notebooks if item.name == notebook_name]
        guid = None
        if notebook:
            guid = notebook[0].guid

        if not guid:
            notebook = GeekNote().createNotebook(notebook_name)

            if(notebook):
                logger.info('Notebook "{0}" was'
                            ' created'.format(notebook_name))
            else:
                raise Exception('Notebook "{0}" was'
                                ' not created'.format(notebook_name))

            guid = notebook.guid

        return (guid, notebook_name)
Example #5
0
    def _create_file(self, note):
        """
        Creates file from note
        """
        GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit).loadNoteContent(note)

        escaped_title = re.sub(os.sep,'-', note.title)

        # Save images
        if 'saveImages' in self.imageOptions and self.imageOptions['saveImages']:
            imageList = Editor.getImages(note.content)
            if imageList:
                if 'imagesInSubdir' in self.imageOptions and self.imageOptions['imagesInSubdir']:
                    os.mkdir(os.path.join(self.path, escaped_title + "_images"))
                    imagePath = os.path.join(self.path, escaped_title + "_images", escaped_title)
                    self.imageOptions['baseFilename'] = escaped_title + "_images/" + escaped_title
                else:
                    imagePath = os.path.join(self.path, escaped_title)
                    self.imageOptions['baseFilename'] = escaped_title
                for imageInfo in imageList:
                    filename = "{}-{}.{}".format(imagePath, imageInfo['hash'], imageInfo['extension'])
                    logger.info('Saving image to {}'.format(filename))
                    binaryHash = binascii.unhexlify(imageInfo['hash'])
                    GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit).saveMedia(note.guid, binaryHash, filename)

        content = Editor.ENMLtoText(note.content.encode('utf-8'), self.imageOptions)
        path = os.path.join(self.path, escaped_title + self.extension)
        open(path, "w").write(content)
        updated_seconds = note.updated / 1000.0
        os.utime(path, (updated_seconds, updated_seconds))
        return True
Example #6
0
 def _get_notes(self):
     """
     Get notes from evernote.
     """
     # keywords = 'notebook:"{0}"'.format(tools.strip(self.notebook_name.encode('utf-8')))
     # keywords = 'intitle:"" notebook:"{0}"'.format(tools.strip(self.notebook_name.encode('utf-8')))
     # unfortunately above not working
     keywords = ''
     gn = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit)
     return gn.findNotes(keywords,
                         EDAM_USER_NOTES_MAX,
                         notebookGuid=self.notebook_guid).notes
Example #7
0
    def _create_file(self, note):
        """
        Creates file from note
        """
        GeekNote(
            sleepOnRateLimit=self.sleep_on_ratelimit).loadNoteContent(note)

        escaped_title = re.sub(os.sep, "-", note.title)

        # Save images
        if "saveImages" in self.imageOptions and self.imageOptions[
                "saveImages"]:
            imageList = Editor.getImages(note.content)
            if imageList:
                if ("imagesInSubdir" in self.imageOptions
                        and self.imageOptions["imagesInSubdir"]):
                    try:
                        os.mkdir(
                            os.path.join(self.path, escaped_title + "_images"))
                    except OSError:
                        # Folder already exists
                        pass
                    imagePath = os.path.join(self.path,
                                             escaped_title + "_images",
                                             escaped_title)
                    self.imageOptions["baseFilename"] = (escaped_title +
                                                         "_images/" +
                                                         escaped_title)
                else:
                    imagePath = os.path.join(self.path, escaped_title)
                    self.imageOptions["baseFilename"] = escaped_title
                for imageInfo in imageList:
                    filename = "{}-{}.{}".format(imagePath, imageInfo["hash"],
                                                 imageInfo["extension"])
                    logger.info("Saving image to {}".format(filename))
                    binaryHash = binascii.unhexlify(imageInfo["hash"])
                    if not GeekNote(sleepOnRateLimit=self.
                                    sleep_on_ratelimit).saveMedia(
                                        note.guid, binaryHash, filename):
                        logger.warning(
                            "Failed to save image {}".format(filename))

        content = Editor.ENMLtoText(note.content, self.imageOptions)
        path = os.path.join(self.path, escaped_title + self.extension)
        open(path, "w").write(content)
        updated_seconds = note.updated / 1000.0
        os.utime(path, (updated_seconds, updated_seconds))
        return True
Example #8
0
 def _get_notes(self, changed_after=None):
     """ Get notes from evernote notebook.
     """
     gn = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit)
     if changed_after is not None:
         # limit number of notes to check using constraint on date updated
         # e.g. 'updated:20070704T150000Z'  # does not work as expected (in EN sandbox)
         # keywords = 'updated:' + changed_after.strftime("%Y%m%dT%H%M%S")  # e.g. 'updated:20070704T20190801' # fails!!
         keywords = 'updated:' + changed_after.strftime(
             "%Y%m%d")  # e.g. 'updated:20070704T20190801'
         # logger.debug("restrict notes using filter: %s", keywords)  # log bloat
     else:
         keywords = ''
     return gn.findNotes(keywords,
                         EDAM_USER_NOTES_MAX,
                         notebookGuid=self.notebook_guid).notes
Example #9
0
    def _update_note(self,
                     file_note,
                     note,
                     title=None,
                     content=None,
                     tags=None):
        """
        Updates note from file
        """
        if content is None:
            content = self._get_file_content(file_note['path'],
                                             file_note['format'])
        try:
            tags = tags or note.tagNames
        except AttributeError:
            tags = None

        result = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit).updateNote(
            guid=note.guid,
            title=title or note.title,
            content=content,
            tags=tags,
            notebook=self.notebook_guid)

        if result:
            logger.info('Note "{0}" was updated'.format(note.title))
        else:
            raise Exception('Note "{0}" was not updated'.format(note.title))

        return result
Example #10
0
    def _create_note(self, file_note, title=None, content=None, tags=None):
        """
        Creates note from file
        """
        content = content or self._get_file_content(file_note['path'],
                                                    file_note['format'])

        if content is None:
            return

        result = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit).createNote(
            title=title or file_note['name'],
            content=content,
            notebook=self.notebook_guid,
            tags=tags or None,
            created=file_note['mtime'])

        if result:
            logger.info('Note "{0}" was created'.format(title
                                                        or file_note['name']))
        else:
            raise Exception('Note "{0}" was not'
                            ' created'.format(title or file_note['name']))

        return result
Example #11
0
 def _update_file(self, file_note, note):
     """
     Updates file from note
     """
     GeekNote().loadNoteContent(note)
     content = Editor.ENMLtoText(note.content)
     open(file_note['path'], "w").write(content)
Example #12
0
 def _get_notes(self):
     """
     Get notes from evernote.
     """
     keywords = 'notebook:"{0}"'.format(
         tools.strip(self.notebook_name.encode("utf-8")))
     return (GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit).findNotes(
         keywords, EDAM_USER_NOTES_MAX).notes)
Example #13
0
    def _create_file(self, note):
        """
        Creates file from note
        """
        GeekNote().loadNoteContent(note)

        escaped_title = note.title.replace(os.sep, '-')
        path = os.path.join(
            self.path,
            escaped_title.decode('utf8').encode(os_encoding) + self.extension)

        if self.format != "enex":
            # Save images
            if 'saveImages' in self.imageOptions and self.imageOptions[
                    'saveImages'] and self.format != "enex":
                imageList = Editor.getImages(note.content)
                if imageList:
                    if 'imagesInSubdir' in self.imageOptions and self.imageOptions[
                            'imagesInSubdir']:
                        os.mkdir(
                            os.path.join(self.path, escaped_title + "_images"))
                        imagePath = os.path.join(self.path,
                                                 escaped_title + "_images",
                                                 escaped_title)
                        self.imageOptions[
                            'baseFilename'] = escaped_title + "_images/" + escaped_title
                    else:
                        imagePath = os.path.join(self.path, escaped_title)
                        self.imageOptions['baseFilename'] = escaped_title
                    for imageInfo in imageList:
                        filename = "{}-{}.{}".format(imagePath,
                                                     imageInfo['hash'],
                                                     imageInfo['extension'])
                        logger.info('Saving image to {}'.format(filename))
                        binaryHash = binascii.unhexlify(imageInfo['hash'])
                        GeekNote().saveMedia(note.guid, binaryHash, filename)
            content = Editor.ENMLtoText(note.content, self.imageOptions)
            open(path, "w").write(content)
        else:
            enex.note_to_file(note, path)

        logger.info("create file {}".format(path))
        updated_seconds = note.updated / 1000.0
        os.utime(path, (updated_seconds, updated_seconds))
        return True
Example #14
0
 def _create_file(self, note):
     """
     Creates file from note
     """
     GeekNote().loadNoteContent(note)
     content = Editor.ENMLtoText(note.content)
     path = os.path.join(self.path, note.title + self.extension)
     open(path, "w").write(content)
     return True
Example #15
0
 def _update_file(self, file_note, note):
     """
     Updates file from note
     """
     GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit).loadNoteContent(note)
     content = Editor.ENMLtoText(note.content)
     open(file_note['path'], "w").write(content)
     updated_seconds = note.updated / 1000.0
     os.utime(file_note['path'], (updated_seconds, updated_seconds))
Example #16
0
 def _get_notes(self):
     """
     Get notes from evernote.
     """
     keywords = 'notebook:"{0}"'.format(tools.strip(self.notebook_name))
     #print GeekNote().findNotes(keywords, 10000)
     #try to get all notes in a notebook
     #assum that the notebook has less than 10000 notes
     noteMetadataResultSpec = NoteStore.NotesMetadataResultSpec(includeTitle=True,\
             includeUpdated=True)
     noteList = GeekNote().findNotesMetadata(keywords, 10000,
                                             noteMetadataResultSpec)
     notes = noteList.notes
     notesSize = len(notes)
     while (notesSize < noteList.totalNotes):
         noteList = GeekNote().findNotesMetadata(keywords,
                                                 10000,
                                                 offset=notesSize)
         notes += noteList.notes
         notesSize = len(notes)
         print notesSize
     return notes
Example #17
0
 def _update_file(self, file_note, note):
     """
     Updates file from note
     """
     GeekNote().loadNoteContent(note)
     print("update {}".format(file_note['path']))
     if self.format != "enex":
         open(file_note['path'], "w").write(content)
         content = Editor.ENMLtoText(note.content)
     else:
         enex.note_to_file(note, file_note['path'])
     updated_seconds = note.updated / 1000.0
     os.utime(file_note['path'], (updated_seconds, updated_seconds))
Example #18
0
    def sync(self):
        """
        Synchronize files to notes
        TODO: add two way sync with meta support
        TODO: add specific notebook support
        """
        if not self.all_set:
            return

        files = self._get_files()
        notes = self._get_notes()

        for f in files:
            has_note = False
            meta = self._parse_meta(self._get_file_content(f['path']))
            title = f['name'] if 'title' not in meta else meta['title'].strip()
            tags = None if 'tags' not in meta else meta['tags'] \
                   .replace('[', '').replace(']','').split(',')
            tags = None if tags == '' else map(lambda x:x.strip(), tags)
            note = None
            if self.format == 'html':
                meta['mtime'] = f['mtime']
                note = self._html2note(meta)

            for n in notes:
                if title == n.title:
                    has_note = True
                    if f['mtime'] > n.updated:
                        if self.format == 'html':
                            gn = GeekNote()
                            note.guid = n.guid
                            gn.getNoteStore().updateNote(gn.authToken, note)
                            logger.info('Note "{0}" was updated'.format(note.title))
                        else:
                            self._update_note(f, n, title, meta['content'], tags)
                        break

            if not has_note:
                if self.format == 'html':
                    gn = GeekNote()
                    gn.getNoteStore().createNote(gn.authToken, note)
                    logger.info('Note "{0}" was created'.format(note.title))
                else:
                    self._create_note(f, title, meta['content'], tags)

        if self.twoway:
            for n in notes:
                has_file = False
                for f in files:
                    if f['name'] == n.title:
                        has_file = True
                        if f['mtime'] < n.updated:
                            self._update_file(f, n)
                            break

                if not has_file:
                    self._create_file(n)

        logger.info('Sync Complete')
Example #19
0
    def _update_note(self, file_note, note):
        """
        Updates note from file
        """
        content = self._get_file_content(file_note['path'])

        result = GeekNote().updateNote(guid=note.guid,
                                       title=note.title,
                                       content=content,
                                       notebook=self.notebook_guid)

        if result:
            logger.info('Note "{0}" was updated'.format(note.title))
        else:
            raise Exception('Note "{0}" was not updated'.format(note.title))

        return result
Example #20
0
    def _update_note(self, file_note, note, title=None, content=None, tags=None):
        """
        Updates note from file
        """
        # content = self._get_file_content(file_note['path']) if content is None else content

        result = GeekNote().updateNote(
            guid=note.guid,
            title=title or note.title,
            content=content or self._get_file_content(file_note['path']),
            tags=tags or note.tagNames,
            notebook=self.notebook_guid)

        if result:
            logger.info('Note "{0}" was updated'.format(note.title))
        else:
            raise Exception('Note "{0}" was not updated'.format(note.title))

        return result
Example #21
0
    def _create_note(self, file_note):
        """
        Creates note from file
        """

        content = self._get_file_content(file_note['path'])

        if content is None:
            return

        result = GeekNote().createNote(title=file_note['name'],
                                       content=content,
                                       notebook=self.notebook_guid)

        if result:
            logger.info('Note "{0}" was created'.format(file_note['name']))
        else:
            raise Exception('Note "{0}" was not created'.format(
                file_note['name']))

        return result
Example #22
0
 def _get_notes(self):
     """
     Get notes from evernote.
     """
     keywords = 'notebook:"{0}"'.format(tools.strip(self.notebook_name))
     return GeekNote().findNotes(keywords, EDAM_USER_NOTES_MAX).notes
Example #23
0
def all_notebooks():
    geeknote = GeekNote()
    return [notebook.name for notebook in geeknote.findNotebooks()]
Example #24
0
    def __init__(self,
                 notebook_name,
                 path,
                 mask,
                 format,
                 twoway=False,
                 download_only=False,
                 nodownsync=False,
                 imageOptions={
                     'saveImages': False,
                     'imagesInSubdir': False
                 }):
        # check auth
        if not Storage().getUserToken():
            raise Exception("Auth error. There is not any oAuthToken.")

        # set path
        if not path:
            raise Exception("Path to sync directories does not select.")

        if not os.path.exists(path):
            raise Exception("Path to sync directories does not exist.")

        self.path = path

        # set mask
        if not mask:
            mask = "*.*"

        self.mask = mask

        # set format
        if not format:
            format = "plain"

        self.format = format

        if format == "markdown":
            self.extension = ".md"
        elif format == "html":
            self.extension = ".html"
        elif format == "enex":
            self.extension = ".enex"
        else:
            self.extension = ".txt"

        print("Download notebook {} in {} file".format(notebook_name,
                                                       self.format))

        self.twoway = twoway
        self.download_only = download_only
        self.nodownsync = nodownsync

        logger.info('Sync Start')

        # set notebook
        self.notebook_guid,\
            self.notebook_name = self._get_notebook(notebook_name, path)

        # set image options
        self.imageOptions = imageOptions

        self.user_info = GeekNote().getUserInfo()

        # all is Ok
        self.all_set = True
Example #25
0
    def sync(self):
        """
        Synchronize files to notes
        TODO: add two way sync with meta support
        TODO: add specific notebook support
        """
        if not self.all_set:
            return

        files = self._get_files()
        notes = self._get_notes()

        if not self.download_only:
            for f in files:
                has_note = False
                content = self._get_file_content(f['path'], f['format'])
                meta = self._parse_meta(content, f['format'])
                title = f['name'] if 'title' not in meta else meta[
                    'title'].strip()
                tags = None if 'tags' not in meta else meta['tags'] \
                    .replace('[', '').replace(']', '').split(',')
                tags = None if not tags else map(lambda x: x.strip(), tags)
                meta['tags'] = tags
                meta['title'] = title
                note = None

                meta['mtime'] = f['mtime']
                if f['format'] == 'html':
                    note = self._html2note(meta)
                elif f['format'] == 'markdown':
                    # note = self._md2note(meta)
                    # as Editor.textToENML converts markdown to HTML, reuse
                    note = self._html2note(meta)
                else:
                    assert False, "unsupported format for upload: %s" % f[
                        'format']

                for n in notes:
                    if title == n.title:
                        has_note = True
                        if f['mtime'] > n.updated:
                            if self.format == 'html':
                                gn = GeekNote(
                                    sleepOnRateLimit=self.sleep_on_ratelimit)
                                note.guid = n.guid
                                gn.getNoteStore().updateNote(
                                    gn.authToken, note)
                                logger.info('Note "{0}" was updated'.format(
                                    note.title))
                            else:
                                self._update_note(f, n, title, meta['content'],
                                                  tags)
                            break

                if not has_note:
                    if self.format == 'html':
                        gn = GeekNote(sleepOnRateLimit=self.sleep_on_ratelimit)
                        gn.getNoteStore().createNote(gn.authToken, note)
                        logger.info('Note "{0}" was created'.format(
                            note.title))
                    else:
                        self._create_note(f, title, meta['content'], tags)

        if self.twoway or self.download_only:
            for n in notes:
                has_file = False
                for f in files:
                    if f['name'] == n.title:
                        has_file = True
                        if f['mtime'] < n.updated:
                            self._update_file(f, n)
                            break

                if not self.nodownsync:
                    if not has_file:
                        self._create_file(n)

        logger.info('Sync Complete')
Example #26
0
    def sync(self):
        """
        Synchronize files to notes
        TODO: add two way sync with meta support
        TODO: add specific notebook support
        """
        if not self.all_set:
            return

        files = self._get_files()
        notes = self._get_notes()

        if not self.download_only:
            for f in files:
                has_note = False
                meta = self._parse_meta(self._get_file_content(f['path']))
                title = f['name'] if 'title' not in meta else meta['title'].strip()
                tags = None if 'tags' not in meta else meta['tags'] \
                    .replace('[', '').replace(']', '').split(',')
                tags = None if not tags else map(lambda x: x.strip(), tags)
                meta['tags'] = tags
                meta['title'] = title
                note = None

                if self.format == 'html':
                    meta['mtime'] = f['mtime']
                    note = self._html2note(meta)

                for n in notes:
                    if title == n.title:
                        has_note = True
                        if f['mtime'] > n.updated:
                            if self.format == 'html':
                                gn = GeekNote()
                                note.guid = n.guid
                                gn.getNoteStore().updateNote(gn.authToken, note)
                                logger.info('Note "{0}" was updated'.format(note.title))
                            else:
                                self._update_note(f, n, title, meta['content'], tags)
                            break

                if not has_note:
                    if self.format == 'html':
                        gn = GeekNote()
                        gn.getNoteStore().createNote(gn.authToken, note)
                        logger.info('Note "{0}" was created'.format(note.title))
                    else:
                        self._create_note(f, title, meta['content'], tags)

        if self.twoway or self.download_only:
            for n in notes:
                has_file = False
                for f in files:
                    if f['name'] == n.title:
                        has_file = True
                        if f['mtime'] < n.updated:
                            self._update_file(f, n)
                            break

                if not self.nodownsync:
                    if not has_file:
                        self._create_file(n)

        logger.info('Sync Complete')
Example #27
0
from time import gmtime, strftime
import base64

import lxml.etree as ET
from lxml.etree import SubElement
# import xml.etree.ElementTree as ET
# from xml.etree.ElementTree import SubElement

from xml.sax.saxutils import escape, unescape

import config
from geeknote import GeekNote
from gnsync import GNSync

os_encoding = locale.getpreferredencoding()
user_info = GeekNote().getUserInfo()


def log(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception, e:
            print e
            traceback.print_exc()
            logger.error("%s", str(e))

    return wrapper


def _list_member(obj):
Example #28
0
def all_linked_notebooks():
    geeknote = GeekNote()
    return geeknote.findLinkedNotebooks()
Example #29
0
def all_notebooks(sleep_on_ratelimit=False):
    geeknote = GeekNote(sleepOnRateLimit=sleep_on_ratelimit)
    return [notebook.name for notebook in geeknote.findNotebooks()]
Example #30
0
def main():
    try:
        parser = argparse.ArgumentParser()
        parser.add_argument('--path', '-p', action='store', help='Path to synchronize directory')
        parser.add_argument('--mask', '-m', action='store', help='Mask of files to synchronize. Default is "*.*"')
        parser.add_argument('--format', '-f', action='store', default='plain', choices=['plain', 'markdown', 'html'], help='The format of the file contents. Default is "plain". Valid values are "plain" "html" and "markdown"')
        parser.add_argument('--notebook', '-n', action='store', help='Notebook name for synchronize. Default is default notebook unless all is selected')
        parser.add_argument('--all', '-a', action='store_true', help='Synchronize all notebooks', default=False)
        parser.add_argument('--all-linked', action='store_true', help='Get all linked notebooks')
        parser.add_argument('--logpath', '-l', action='store', help='Path to log file. Default is GeekNoteSync in home dir')
        parser.add_argument('--two-way', '-t', action='store_true', help='Two-way sync (also download from evernote)', default=False)
        parser.add_argument('--download-only', action='store_true', help='Only download from evernote; no upload', default=False)
        parser.add_argument('--nodownsync', '-d', action='store', help='Sync from Evernote only if the file is already local.')
        parser.add_argument('--save-images', action='store_true', help='save images along with text')
        parser.add_argument('--sleep-on-ratelimit', action='store_true', help='sleep on being ratelimited')
        parser.add_argument('--images-in-subdir', action='store_true', help='save images in a subdirectory (instead of same directory as file)')

        args = parser.parse_args()

        path = args.path if args.path else "."
        mask = args.mask if args.mask else None
        format = args.format if args.format else None
        notebook = args.notebook if args.notebook else None
        logpath = args.logpath if args.logpath else None
        twoway = args.two_way
        download_only = args.download_only
        nodownsync = True if args.nodownsync else False

        # image options
        imageOptions = {}
        imageOptions['saveImages'] = args.save_images
        imageOptions['imagesInSubdir'] = args.images_in_subdir

        reset_logpath(logpath)

        
        geeknote = GeekNote()
        

        if args.all_linked:
            my_map = {}
            for notebook in all_linked_notebooks():
                print "Syncing notebook: " + notebook.shareName
                notebook_url = urlparse.urlparse(notebook.noteStoreUrl)
                sharedNoteStoreClient = THttpClient.THttpClient(notebook.noteStoreUrl)
                sharedNoteStoreProtocol = TBinaryProtocol.TBinaryProtocol(sharedNoteStoreClient)
                sharedNoteStore = NoteStore.Client(sharedNoteStoreProtocol) 

                sharedAuthResult = sharedNoteStore.authenticateToSharedNotebook(notebook.shareKey, geeknote.authToken)
                sharedAuthToken = sharedAuthResult.authenticationToken
                sharedNotebook = sharedNoteStore.getSharedNotebookByAuth(sharedAuthToken)

                my_filter = NoteStore.NoteFilter(notebookGuid = sharedNotebook.notebookGuid)

                noteList = sharedNoteStore.findNotes(sharedAuthToken, my_filter, 0, 10)

                print "Found " + str(noteList.totalNotes) + " shared notes."
            
                print noteList.notes

                filename = notebook.shareName + '-' + noteList.notes[0].title + '.html'

                filename = filename.replace(' ','-').replace('/', '-')

                content = sharedNoteStore.getNoteContent(sharedAuthToken, noteList.notes[0].guid) 


                with open(filename, 'w') as f:
                    f.write(content)
                
            

            return

        if args.all:
            for notebook in all_notebooks(sleep_on_ratelimit=args.sleep_on_ratelimit):
                logger.info("Syncing notebook %s", notebook)
                escaped_notebook_path = re.sub(os.sep, '-', notebook)
                notebook_path = os.path.join(path, escaped_notebook_path)
                if not os.path.exists(notebook_path):
                    os.mkdir(notebook_path)
                GNS = GNSync(notebook, notebook_path, mask, format, twoway, download_only, nodownsync, sleep_on_ratelimit=args.sleep_on_ratelimit, imageOptions=imageOptions)
                GNS.sync()
        else:
            GNS = GNSync(notebook, path, mask, format, twoway, download_only, nodownsync, sleep_on_ratelimit=args.sleep_on_ratelimit, imageOptions=imageOptions)
            GNS.sync()

        

    except (KeyboardInterrupt, SystemExit, tools.ExitException):
        pass

    except Exception, e:
        logger.error(str(e))
Example #31
0
def note_to_file(note, path):
    old_tree = None
    if os.path.isfile(path):
        print("parse file {}".format(path))
        try:
            old_tree = ET.parse(path)
        except:
            print("fail")
    enex_file = open(path, "wb+")
    enex_file.write(
        '<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE en-export PUBLIC "SYSTEM" "http://xml.evernote.com/pub/evernote-export3.dtd">\n'
    )
    export_elm = ET.Element('en-export')
    tree = ET.ElementTree(export_elm)
    note_elm = SubElement(export_elm, 'note')
    title_elm = SubElement(note_elm, 'title')
    title_elm.text = note.title.decode('utf-8')
    content_elm = SubElement(note_elm, "content")
    print_title = title_elm.text.encode(os_encoding)
    content_elm.text = ET.CDATA(note.content.decode('utf-8'))
    SubElement(note_elm,
               'created').text = strftime("%Y%m%dT%H%M%SZ",
                                          gmtime(note.created / 1000))
    SubElement(note_elm,
               'updated').text = strftime("%Y%m%dT%H%M%SZ",
                                          gmtime(note.updated / 1000))

    if (note.tagGuids):
        for tag in note.tagNames:
            SubElement(note_elm, 'tag').text = tag

    note_attr_elm = SubElement(note_elm, 'note-attributes')

    upper_regex = re.compile("[A-Z]")
    first_cap_re = re.compile('(.)([A-Z][a-z]+)')
    all_cap_re = re.compile('([a-z0-9])([A-Z])')

    def _conv_export_name(name):
        s1 = first_cap_re.sub(r'\1_\2', name)
        return all_cap_re.sub(r'\1_\2', s1).lower()

    for attr_name, attr in note.attributes.__dict__.items():
        #         print (attr_name, type(attr), attr)
        if attr != None:
            attr_name = _conv_export_name(attr_name)
            if isinstance(attr, basestring):
                SubElement(note_attr_elm,
                           attr_name).text = attr.decode("utf-8")
            if isinstance(attr, long):
                if ('time' in attr_name or 'date' in attr_name):
                    SubElement(note_attr_elm, attr_name).text = strftime(
                        "%Y%m%dT%H%M%SZ", gmtime(attr / 1000))
                else:
                    SubElement(note_attr_elm, attr_name).text = str(attr)
            if isinstance(attr, (float, bool)):
                SubElement(note_attr_elm, attr_name).text = str(attr)

    if (note.largestResourceSize) is not None:
        print("largest resource size of {} = {} ".format(
            print_title, note.largestResourceSize))
        note_obj = GeekNote().getNote(note.guid,
                                      withResourcesData=True,
                                      withResourcesRecognition=True)
        for res in note_obj.resources:
            res_elm = SubElement(note_elm, 'resource')
            print("found resource with size {} in {} ".format(
                res.data.size, print_title))
            SubElement(res_elm, 'data', encoding="base64").text = str(
                base64.b64encode(res.data.body))
            SubElement(res_elm, 'mime').text = res.mime
            if res.width != None:
                SubElement(res_elm, 'width').text = str(res.width)
            if res.height != None:
                SubElement(res_elm, 'height').text = str(res.height)
            if res.recognition != None:
                SubElement(res_elm, 'recognition').text = ET.CDATA(
                    res.recognition.body.decode("utf-8"))
            res_attr_elm = SubElement(res_elm, 'resource-attributes')

            for attr_name, attr in res.attributes.__dict__.items():
                if attr == None:
                    continue
                attr_name = _conv_export_name(attr_name)
                if isinstance(attr, basestring):
                    attr = attr.decode("utf-8")
                    SubElement(res_attr_elm, attr_name).text = attr
                if ('time' in attr_name or 'date' in attr_name):
                    SubElement(res_attr_elm, attr_name).text = strftime(
                        "%Y%m%dT%H%M%SZ", gmtime(attr / 1000))
                if isinstance(attr, (float, bool)):
                    SubElement(res_attr_elm, attr_name).text = str(attr)

    if (old_tree != None):
        prst_servers_info = old_tree.find("server_info")
        if prst_servers_info is not None:
            for account in prst_servers_info:
                if account.find("note_id").text == note.guid:
                    print("Remove old server info")
#                     prst_servers_info.remove(account)

#             print (server.find("base_site"))
#             print ("note stored in {} with account {}".format(server.find("base_site").text,(server.find("account").text)))
#     _list_member(user_info)
    server_elm = SubElement(export_elm, 'server_info')
    account_elm = SubElement(server_elm, 'account')
    SubElement(account_elm, "note_id").text = note.guid
    SubElement(account_elm, "notebook_name").text = note.notebookName
    SubElement(account_elm, "user_id").text = str(user_info.id)
    SubElement(account_elm,
               "user_full_name").text = user_info.name.decode("utf-8")
    SubElement(account_elm, "base_site").text = config.USER_BASE_URL
    SubElement(account_elm, "last_update").text = str(note.updated)

    enex_file.write(
        unescape(ET.tostring(export_elm, encoding='utf-8', pretty_print=True)))
    enex_file.truncate()
    return True
Example #32
0
def all_notebooks():
    geeknote = GeekNote()
    return [notebook.name for notebook in geeknote.findNotebooks()]