-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpinku.py
executable file
·199 lines (148 loc) · 5.68 KB
/
pinku.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/env python3
import argparse
import datetime
import os
import buku
import pinboard
class Pinku(object):
"""Retrieves Pinboard bookmarks adds them to a buku database.
Parameters
----------
api_key : str
Pinboard API key
Attributes
----------
buku : A buku Db object
pb : a Pinboard API wrapper object
"""
def __init__(self, api_key, filters=None, private_only=False, public_only=False, toread_only=False, read_only=False):
self.buku = buku.BukuDb()
self.pb = pinboard.Pinboard(api_key)
self.filters = filters
self.private_only = private_only
self.public_only = public_only
self.toread_only = toread_only
self.read_only = read_only
def import_bookmarks(self):
"""Get bookmarks from Pinboard and add them to buku.
Parameters
----------
filters : dict
Filters for retrieving Pinboard bookmarks.
"""
if self.filters.get('fromdt'):
if not self._check_update(self.filters['fromdt']):
return
records = self._get_pb_bookmarks()
self._add_to_buku(records)
def _check_update(self, date):
"""Check if there are new Pinboard bookmarks since a given date.
Returns
-------
bool
True if there are new bookmarks, else False.
"""
last_update = self.pb.posts.update()
if date > last_update:
print("No Pinboard bookmarks since {}".format(last_update))
return False
return True
def _get_pb_bookmarks(self):
"""Retrieves Pinboard bookmarks."""
return self.pb.posts.all(**self.filters)
def _format_tags(self, tags):
"""Formats tags to conform to buku style.
Tags are wrapped anddelimited by commas.
Parameters
----------
tags : list
List of Pinboard tags for a given bookmark.
Returns
-------
str
Comma delimited string of tags.
"""
tags = ',{},'.format(','.join(tags))
return tags
def _add_to_buku(self, records):
"""Adds Pinboard bookmarks to buku Db
Parameters
----------
rec : list
A list of new Pinboard bookmarks to add to buku Db.
"""
added = 0
for rec in records:
if self.private_only and rec.shared:
continue
if self.public_only and not rec.shared:
continue
if self.toread_only and not rec.toread:
continue
if self.read_only and rec.toread:
continue
if self.buku.get_rec_id(rec.url) == -1:
resp = self.buku.add_rec(rec.url,
title_in=rec.description,
tags_in=self._format_tags(rec.tags),
desc=rec.extended)
if resp == -1:
print("Could not add '{}'".format(rec))
else:
added += 1
print("Added {} bookmarks to buku".format(added))
def valid_date(date):
"""Convert date string to Datetime object.
Parameters
----------
date : str
User supplied date.
Returns
-------
Datetime object
"""
try:
return datetime.datetime.strptime(date, "%Y-%m-%d")
except ValueError:
msg = "Not a valid date: '{0}'.\nDates must be in 'Year-month-day' format".format(date)
raise argparse.ArgumentTypeError(msg)
def create_pinku(api_key, **kwargs):
"""Creates a Pinku object."""
private_only = kwargs.pop('private', None)
public_only = kwargs.pop('public', None)
toread_only = kwargs.pop('toread', None)
read_only = kwargs.pop('read', None)
filters = {k: v for k, v in kwargs.items() if v }
return Pinku(api_key, filters=filters, private_only=private_only, public_only=public_only, toread_only=toread_only, read_only=read_only)
def main():
pb_api_key = os.environ.get('PINBOARD_API_KEY')
if not pb_api_key:
print("PINBOARD_API_KEY environment variable not found")
return
parser = argparse.ArgumentParser()
parser.add_argument('--private', action='store_true', default=False,
help="Only retrieve bookmarks with 'shared' status")
parser.add_argument('--public', action='store_true', default=False,
help="Only retrieve bookmarks without 'shared' status")
parser.add_argument('--toread', action='store_true', default=False,
help="Only retrieve bookmarks with 'to read' status")
parser.add_argument('--read', action='store_true', default=False,
help="Only retrieve bookmarks without 'to read' status")
filters = parser.add_argument_group('filters')
filters.add_argument('-t', '--tag', nargs='*',
help="Filter by up to three tags")
filters.add_argument('-s', '--start',
help="Offset value")
filters.add_argument('-r', '--results',
help="Number of results to return")
filters.add_argument('--fromdt', type=valid_date,
help="Datetime. Return only bookmarks created after this time.")
filters.add_argument('--todt', type=valid_date,
help="Return only bookmarks created before this time")
filters.add_argument('--meta',
help="Include a change detection signature for each bookmark")
args = parser.parse_args()
pinku = create_pinku(pb_api_key, **vars(args))
pinku.import_bookmarks()
if __name__ == "__main__":
main()