From 143ab9e375fca6d50ff1543527ec0d608d4967a4 Mon Sep 17 00:00:00 2001 From: Jeff Hatz Date: Wed, 13 Jan 2016 22:47:11 -0700 Subject: [PATCH 1/2] Update to work with Vesper 2 --- README.md | 5 ----- vesper-export.py | 31 +++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 4421e06..9c43b8b 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,6 @@ A script to export your notes from the [Vesper](http://vesperapp.co) iOS app to text files. Exported notes can include markdown formatting with the `--markdown` switch. -## Known Issues - -- This was developed against Vesper 1.003. The data model has changed in newer versions and the script is incompatible with version 2+. -- Supporting new Vesper data model versions is a moving target. The syncing feature added in 2.0 removes the need for exporting for backup. That said, patches are welcome. - ## Usage - Using a tool like [PhoneView](https://www.ecamm.com/mac/phoneview/): diff --git a/vesper-export.py b/vesper-export.py index 9076b72..4d99c43 100755 --- a/vesper-export.py +++ b/vesper-export.py @@ -14,30 +14,49 @@ def exportNotes(cursor, destDir, markdownify=False): print "Exporting to '%s':" % destDir - query = "SELECT uniqueId,text,archived,attachmentUniqueID,tags from notes;" - for record in cursor.execute(query): + + rowsNotes = cursor.execute("SELECT uniqueId,text,archived,thumbnailID,creationDate,textModificationDate from notes;").fetchall() + rowsTags = cursor.execute("SELECT tagID,noteID from tagsNotesLookup;").fetchall() + + for record in rowsNotes: id = record[0] text = record[1].encode("utf-8") if record[1] else None archived = bool(record[2]) imageId = record[3].encode("utf-8") if record[3] else None - tags = record[4].encode("utf-8") if record[4] else None + dateCreated = record[4] + dateModified = record[5] if record[5] != None else dateCreated + tags = "" + + tagCount = 0 + for tagRecord in rowsTags: + tagName = tagRecord[0].encode("utf-8") + noteID = tagRecord[1] + + if noteID == id: + seperator = ", " if tagCount > 0 else "" + tags += seperator + tagName + tagCount += 1 ext = ".md" if markdownify else ".txt" title = text.splitlines()[0].strip() + ext + title = title[:255].replace("/", "-") path = os.path.join(destDir,title) file = open(path, "w") if imageId: if markdownify: - file.write("![Header Image](images/%s)\n\n" % imageId) + file.write("![Header Image](images/{0})\n\n".format(imageId)) else: - file.write("Image: images/%s\n\n", imageId) + file.write("Image: images/{0}\n\n".format(imageId)) if markdownify: file.write("# ") file.write(text) if tags: - file.write("\nTags: %s" % tags) + file.write("\nTags: {0}".format(tags)) file.close() + + os.utime(path, (dateCreated, dateModified)) + print " Exported '%s'" % title print "Done" pass From c955dad928efacc4f0a5644de50adfa3fcd95a0f Mon Sep 17 00:00:00 2001 From: Jeff Hatz Date: Fri, 15 Jan 2016 01:40:49 -0700 Subject: [PATCH 2/2] Parse tags into dictionary ahead of time --- vesper-export.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/vesper-export.py b/vesper-export.py index 4d99c43..6f47231 100755 --- a/vesper-export.py +++ b/vesper-export.py @@ -18,24 +18,27 @@ def exportNotes(cursor, destDir, markdownify=False): rowsNotes = cursor.execute("SELECT uniqueId,text,archived,thumbnailID,creationDate,textModificationDate from notes;").fetchall() rowsTags = cursor.execute("SELECT tagID,noteID from tagsNotesLookup;").fetchall() + # Parse tags into a dictionary[noteID:[tagNames]] + tags = {} + for tag in rowsTags: + tagName = tag[0].encode("utf-8") + noteID = str(tag[1]) + + itemTags = [] + if set([noteID]).issubset(tags): + itemTags = tags[noteID] + + itemTags.append(tagName) + tags[noteID] = itemTags + for record in rowsNotes: - id = record[0] + id = str(record[0]) text = record[1].encode("utf-8") if record[1] else None archived = bool(record[2]) imageId = record[3].encode("utf-8") if record[3] else None dateCreated = record[4] dateModified = record[5] if record[5] != None else dateCreated - tags = "" - - tagCount = 0 - for tagRecord in rowsTags: - tagName = tagRecord[0].encode("utf-8") - noteID = tagRecord[1] - - if noteID == id: - seperator = ", " if tagCount > 0 else "" - tags += seperator + tagName - tagCount += 1 + recordTags = tags[id] if set([id]).issubset(tags) else None ext = ".md" if markdownify else ".txt" title = text.splitlines()[0].strip() + ext @@ -51,8 +54,8 @@ def exportNotes(cursor, destDir, markdownify=False): if markdownify: file.write("# ") file.write(text) - if tags: - file.write("\nTags: {0}".format(tags)) + if recordTags: + file.write("\nTags: {0}".format( ", ".join(recordTags) )) file.close() os.utime(path, (dateCreated, dateModified))