A python script that saves items edited in Kobito to Evernote
You can't create text with markdown in Evernote, but with Kobito!
Save the HTML rendered by Kobito to Evernote as it is. For items updated with Kobito, we will update the corresponding Evernote notes. The tags on the Kobito side will also be reflected in Evernote. When you publish an item on Qiita, the public URL will be reflected in Evernote.
Save recently updated items in Kobito to Evernote.
The destination notebook is Kobito
. If not, it will be made.
The "recent" judgment is made by the time stamp saved in the file last_kobito
created in the directory where the script is executed.
The interaction with Evernote is AppleScript.
Update monitoring is not performed, so please execute it regularly with cron etc.
There is no guarantee. It shouldn't be code that loses content on Kobito / Evernote, but please at your own risk.
If the specifications of Kobito change, it may suddenly stop working.
git clone git://github.com/naoyat/qiita-toolkit.git
kobitonote.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
##
## kobitonote -Save Kobito items to Evernote
##
## (c)2012 by @naoya_t
##
import os
import re
import sqlite3
import subprocess
import sys
import time
##Destination notebook
NOTEBOOK_FOR_KOBITO = 'Kobito'
## Kobito.db location PATH
DB_PATH = os.environ['HOME'] + '/Library/Kobito/Kobito.db'
## Kobito.db internal time offset
TIME_OFFSET = 978307200.0 # time.mktime(time.strptime("Mon Jan 1 09:00:00 2001"))
##Last processed timestamp
LAST_KOBITO = './last_kobito'
##Seconds → ISO-8601 format
def iso_8601_jst(t):
return time.strftime('%Y-%m-%dT%H:%M:%S+09:00', time.localtime(t))
##AppleScript generation
def make_script(title, body, created_at, updated_at, tags, url=None):
def osa_escape(string):
return string.replace('¥¥', '¥¥¥¥').replace('"', '¥¥"')
def my_datetime(t):
return time.strftime('my datetime(%Y,%m,%d,%H,%M,%S)', time.localtime(t))
def make_tag_list(tags):
return '{' + ','.join(['"'+osa_escape(tag)+'"' for tag in tags]) + '}'
return """
on datetime(year, mon, day, hour, min, sec)
set d to current date
set d's year to year
set d's month to mon
set d's day to day
set d's hours to hour
set d's minutes to min
set d's seconds to sec
return d
end datetime
tell application "Evernote"
set notebookStr to "%s"
set titleStr to "%s"
set htmlStr to "%s"
set createdAt to %s
set updatedAt to %s
set tagNameList to %s
set urlStr to %s
if not exists notebook notebookStr then
make new notebook with properties {name:notebookStr}
end if
set tagList to {}
repeat with aTagName in tagNameList
if exists tag aTagName then
set aTag to tag aTagName
else
set aTag to make new tag with properties {name:aTagName}
end if
set end of tagList to aTag
end repeat
set destNote to null
repeat with aNote in (find notes "notebook:" & notebookStr & " intitle:¥¥"" & titleStr & "¥¥"")
if aNote's creation date = createdAt then
set destNote to aNote
end if
end repeat
if destNote = null then
set destNote to (create note with html htmlStr title titleStr notebook notebookStr created createdAt tags tagList)
else
set destNote's title to titleStr
set destNote's HTML content to htmlStr
set destNote's tags to tagList
end if
set destNote's modification date to updatedAt
if not urlStr is equal to "" then
set destNote's source URL to urlStr
end if
end tell
""" % (NOTEBOOK_FOR_KOBITO,
osa_escape(title),
osa_escape(body),
my_datetime(created_at),
my_datetime(updated_at),
make_tag_list(tags),
'"'+url+'"' if url else '""')
##Run applescript
def run_osascript(script, *args):
p = subprocess.Popen(['arch', '-i386', 'osascript', '-e', script] +
[unicode(arg).encode('utf8') for arg in args],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
err = p.wait()
if err:
raise RuntimeError(err, p.stderr.read()[:-1].decode('utf8'))
return p.stdout.read()[:-1].decode('utf8')
##Kobito item class
class KobitoItem :
def __init__(self, row, items_tags={}):
z_pk, z_ent, z_opt, zprivate, zteam, zcreated_at, zposted_at, zupdated_at, ¥
zupdated_at_on_qiita, zbody, zkey, zlinked_file, zraw_body, ztitle, zurl, zuuid = row
self._pk = z_pk
self._ent = z_ent
self._opt = z_opt
self.private = zprivate
self.team = zteam
self.created_at = TIME_OFFSET + zcreated_at if zcreated_at else None
self.posted_at = TIME_OFFSET + zposted_at if zposted_at else None
self.updated_at = TIME_OFFSET + zupdated_at if zupdated_at else None
self.updated_at_on_qiita = TIME_OFFSET + zupdated_at_on_qiita if zupdated_at_on_qiita else None
self.body = zbody.encode('utf-8')
self.key = zkey.encode('utf-8')
self.linked_file = zlinked_file
self.raw_body = zraw_body.encode('utf-8')
self.title = ztitle.encode('utf-8')
self.url = zurl.encode('utf-8') if zurl else None
self.uuid = zuuid #
self.tags = items_tags[z_pk] if items_tags.has_key(z_pk) else []
def save_in_evernote(self):
title = self.title
body = self.body ¥
.replace("<!DOCTYPE HTML>¥n", "") ¥
.replace('rel="stylesheet" href="',
'rel="stylesheet" href="/Applications/Kobito.app/Contents/Resources/')
body = re.sub(r'[ ¥t]*<script[^¥n]*</script>¥n', r'', body)
body = re.sub(r' <body>¥n<h1>[^¥n]*</h1>', r'<body>', body)
script = make_script(title, body, self.created_at, self.updated_at, self.tags, self.url)
# print script
sys.stderr.write(iso_8601_jst(self.updated_at))
sys.stderr.write("「" + self.title + "」")
sys.stderr.write(" ".join(self.tags) + "¥n")
run_osascript(script)
##Get the tag on the Kobito side
def get_kobito_tags(conn):
c = conn.cursor()
c.execute(u"select * from ZTAG")
tags = {}
for _pk, _ent, _opt, name in c:
tags[_pk] = name.encode('utf-8')
return tags
##Get tags attached to Kobito items
## {Item ID 1: [Tag ID1,Tag ID2, ...],Item ID 2: [...], ...}
##If the tag has been acquired, replace the tag ID with a character string
## {Item ID 1: [Tag 1,Tag 2, ...],Item ID 2: [...], ...}
def get_kobito_items_tags(conn, tags=None):
items_tags = {}
c = conn.cursor()
c.execute(u"select * from Z_1TAGS")
for _1items, _2tags in c:
if tags:
_2tags = tags[_2tags]
if items_tags.has_key(_1items):
items_tags[_1items].append(_2tags)
else:
items_tags[_1items] = [_2tags]
return items_tags
##Get Kobito items
def get_kobito_items(conn, last, items_tags=None):
c = conn.cursor()
c.execute(u"select * from ZITEM where ZUPDATED_AT > %s" % str(last))
return [KobitoItem(row, items_tags) for row in c]
##Save recent updates (= since the last time you ran this script) in evernote
##Evernote deduplication created_Match only by at and title
def save_recent_to_evernote():
def last_kobito_time():
if os.path.exists(LAST_KOBITO):
with open(LAST_KOBITO, 'r') as fp:
return float(fp.readline().rstrip())
else:
return 0
def save_current_kobito_time():
current_kobito_time = time.time() - TIME_OFFSET
with open(LAST_KOBITO, 'w') as fp:
fp.write(str(current_kobito_time) + '¥n')
conn = sqlite3.connect(DB_PATH)
tags = get_kobito_tags(conn)
items_tags = get_kobito_items_tags(conn, tags)
for item in get_kobito_items(conn, last_kobito_time(), items_tags):
item.save_in_evernote()
conn.close()
save_current_kobito_time()
if __name__ == '__main__':
save_recent_to_evernote()
Recommended Posts