/
pinboard-to-mt.py
151 lines (118 loc) · 4.95 KB
/
pinboard-to-mt.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# -*- coding: utf-8 -*-
import ConfigParser
import datetime
import MySQLdb
import pinboard
import sys
import urllib2
class PinboardToMT:
def __init__(self, date=None):
if date is None:
self.date = datetime.datetime.utcnow().date()
else:
self.date = datetime.datetime.strptime(date, "%Y-%m-%d").date()
self.load_config()
def load_config(self):
config_file = sys.path[0] + '/pinboard.cfg'
config = ConfigParser.SafeConfigParser()
try:
config.readfp(open(config_file))
except IOError:
raise PinboardToMTError("Can't read config file: " + config_file)
settings = {'pinboard_api_token': 'string',
'mt_blog_id': 'integer',
'mt_author_id': 'integer',
'mt_post_time': 'string',
'include_tags': 'integer',
'db_host': 'string',
'db_name': 'string',
'db_user': 'string',
'db_password': 'string',
'verbose': 'integer',
}
for setting, tp in settings.iteritems():
if tp == 'integer':
setattr(self, setting, config.getint('Settings', setting))
else:
setattr(self, setting, config.get('Settings', setting))
# Assuming the Pinboard API token is always of the form
# 'username:SOMECHARACTERS'
self.pinboard_username = self.pinboard_api_token[:self.pinboard_api_token.index(':')]
def start(self):
links = self.get_pinboard_links()
if len(links) == 0:
return
self.make_blog_post(links)
def get_pinboard_links(self):
try:
p = pinboard.open(token=self.pinboard_api_token)
except urllib2.HTTPError, error:
raise PinboardToMTError("Can't connect to Pinboard: %s" % error)
links = p.posts(date=self.date.strftime('%Y-%m-%d'))
self.message("Fetched %s link(s) from Pinboard." % len(links))
return links
def make_blog_post(self, links):
html = self.make_html(links)
title = "Links for %s %s %s" % (self.date.strftime('%A'),
self.date.strftime('%d').lstrip('0'),
self.date.strftime('%B %Y'))
try:
db = MySQLdb.connect(host=self.db_host, user=self.db_user,
passwd=self.db_password, db=self.db_name)
except MySQLdb.OperationalError, error:
raise PinboardToMTError("Problem connecting to database: %s" % error)
db.set_character_set('utf8')
cur = db.cursor()
cur.execute('SET NAMES utf8;')
cur.execute('SET CHARACTER SET utf8;')
cur.execute('SET character_set_connection=utf8;')
try:
cur.execute("""INSERT INTO mt_entry (entry_blog_id, entry_author_id,
entry_title, entry_text, entry_created_on, entry_authored_on,
entry_created_by, entry_status, entry_current_revision)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)""", (
self.mt_blog_id,
self.mt_author_id,
title,
html,
datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S'),
self.date.strftime('%Y-%m-%d 23:58:00'),
self.mt_author_id,
4, # Scheduled
0
))
except UnicodeEncodeError, error:
raise PinboardToMTError("Unicode encoding error: %s" % error)
self.message("Added Movable Type entry (ID %s)." % db.insert_id())
def make_html(self, links):
"""The HTML that will be the blog entry."""
html = ''
for link in links:
html += "<dt><a href=\"%s\">%s</a></dt>\n<dd>" % (
link['href'], link['description'])
if link.get('extended', False):
html += link['extended']
if self.include_tags:
tags = []
for tag in link.get('tags', []):
tags.append(
'<a href="https://pinboard.in/u:%s/t:%s">%s</a>' % (
self.pinboard_username, tag, tag))
html += ' <span class="tags">%s</span>' % ', '.join(tags)
html += "</dd>\n"
html = "<dl class=\"links\">\n%s</dl>\n" % html
return html
def message(self, text):
"Output debugging info, if in verbose mode."
if self.verbose:
print text
class PinboardToMTError(Exception):
pass
def main():
date = None
if len(sys.argv) == 2:
date = sys.argv[1]
p = PinboardToMT(date)
p.start()
if __name__ == "__main__":
main()