forked from bookieio/Bookie
/
bmarks.py
323 lines (279 loc) · 10.1 KB
/
bmarks.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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
"""Controllers related to viewing lists of bookmarks"""
import logging
from pyramid.httpexceptions import HTTPFound
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import view_config
from bookie.bcelery import tasks
from bookie.lib.access import ReqAuthorize
from bookie.lib.utils import suggest_tags
from bookie.lib.urlhash import generate_hash
from bookie.models import (
Bmark,
BmarkMgr,
DBSession,
InvalidBookmark,
NoResultFound,
TagMgr,
)
from bookie.views import api
LOG = logging.getLogger(__name__)
RESULTS_MAX = 50
@view_config(
route_name="bmark_recent",
renderer="/bmark/recent.mako")
@view_config(
route_name="bmark_recent_tags",
renderer="/bmark/recent.mako")
@view_config(
route_name="user_bmark_recent",
renderer="/bmark/recent.mako")
@view_config(
route_name="user_bmark_recent_tags",
renderer="/bmark/recent.mako")
def recent(request):
"""Testing a JS driven ui with backbone/etc"""
rdict = request.matchdict
params = request.params
# Make sure we generate a url to feed our rss link.
current_route = request.current_route_url()
# check for auth related stuff
# are we looking for a specific user
username = rdict.get('username', None)
if username:
username = username.lower()
# do we have any tags to filter upon
tags = rdict.get('tags', None)
if isinstance(tags, str):
tags = [tags]
ret = {
'username': username,
'tags': tags,
'rss_url': current_route.replace('recent', 'rss')
}
# if we've got url parameters for the page/count then use those to help
# feed the init of the ajax script
ret['count'] = params.get('count') if 'count' in params else RESULTS_MAX
ret['page'] = params.get('page') if 'page' in params else 0
# Do we have any sorting criteria?
ret['sort'] = params.get('sort') if 'sort' in params else None
return ret
@view_config(
route_name="bmark_recent_rss",
renderer="/bmark/rss.mako")
@view_config(
route_name="bmark_recent_rss_tags",
renderer="/bmark/rss.mako")
@view_config(
route_name="user_bmark_rss",
renderer="/bmark/rss.mako")
@view_config(
route_name="user_bmark_rss_tags",
renderer="/bmark/rss.mako")
def recent_rss(request):
rdict = request.matchdict
request.response.content_type = 'application/atom+xml; charset=UTF-8'
tags = rdict.get('tags', None)
username = rdict.get('username', None)
if username:
username = username.lower()
ret = api.bmark_recent(request, with_content=True)
ret['username'] = username
ret['tags'] = tags
return ret
@view_config(
route_name="user_bmark_edit",
renderer="/bmark/edit.mako")
@view_config(
route_name="user_bmark_new",
renderer="/bmark/edit.mako")
def edit(request):
"""Manual add a bookmark to the user account
Can pass in params (say from a magic bookmarklet later)
url
description
extended
tags
"""
rdict = request.matchdict
params = request.params
url = params.get('url', u"")
title = params.get('description', None)
new = False
MAX_TAGS = 10
tag_suggest = []
base_tags = set()
with ReqAuthorize(request, username=rdict['username'].lower()):
if 'hash_id' in rdict:
hash_id = rdict['hash_id']
elif 'hash_id' in params:
hash_id = params['hash_id']
else:
hash_id = None
if hash_id:
bmark = BmarkMgr.get_by_hash(hash_id, request.user.username)
if bmark is None:
return HTTPNotFound()
else:
title = bmark.description
url = bmark.hashed.url
else:
# Hash the url and make sure that it doesn't exist
if url != u"":
new_url_hash = generate_hash(url)
test_exists = BmarkMgr.get_by_hash(
new_url_hash,
request.user.username)
if test_exists:
location = request.route_url(
'user_bmark_edit',
hash_id=new_url_hash,
username=request.user.username)
return HTTPFound(location)
# No url info given so shown the form to the user.
new = True
# Setup a dummy bookmark so the template can operate
# correctly.
bmark = Bmark(url, request.user.username, desc=title)
# Title and url will be in params for new bookmark and
# fetched from database if it is an edit request
if title or url:
suggested_tags = suggest_tags(url)
suggested_tags.update(suggest_tags(title))
base_tags.update(suggested_tags)
# If user is editing a bookmark, suggested tags will include tags
# based on readable content also
if not new:
tag_suggest = TagMgr.suggestions(
bmark=bmark,
url=bmark.hashed.url,
username=request.user.username
)
# tags based on url and title will always be there
# order of tags is important so convert set to list
tag_suggest.extend(list(base_tags))
tag_suggest = (tag_suggest[0:MAX_TAGS],
tag_suggest)[len(tag_suggest) < MAX_TAGS]
return {
'new': new,
'bmark': bmark,
'user': request.user,
'tag_suggest': list(set(tag_suggest)),
}
@view_config(route_name="user_bmark_edit_error", renderer="/bmark/edit.mako")
@view_config(route_name="user_bmark_new_error", renderer="/bmark/edit.mako")
def edit_error(request):
rdict = request.matchdict
params = request.params
post = request.POST
with ReqAuthorize(request, username=rdict['username'].lower()):
if 'is_private' in post:
post['is_private'] = True
else:
post['is_private'] = False
if 'new' in request.url:
try:
try:
bmark = BmarkMgr.get_by_url(
post['url'],
username=request.user.username)
except NoResultFound:
bmark = None
if bmark:
return {
'new': False,
'bmark': bmark,
'message': "URL already Exists",
'user': request.user,
}
else:
bmark = BmarkMgr.store(
url=post['url'],
username=request.user.username,
desc=post['description'],
ext=post['extended'],
tags=post['tags'],
is_private=post['is_private'])
# Assign a task to fetch this pages content and parse it
# out for storage and indexing.
DBSession.flush()
tasks.fetch_bmark_content.delay(bmark.bid)
except InvalidBookmark, exc:
# There was an issue using the supplied data to create a new
# bookmark. Send the data back to the user with the error
# message.
bmark = Bmark(
post['url'],
request.user.username,
desc=post['description'],
ext=post['extended'],
tags=post['tags'],
is_private=post['is_private'])
return {
'new': True,
'bmark': bmark,
'message': exc.message,
'user': request.user,
}
else:
if 'hash_id' in rdict:
hash_id = rdict['hash_id']
elif 'hash_id' in params:
hash_id = params['hash_id']
bmark = BmarkMgr.get_by_hash(hash_id, request.user.username)
if bmark is None:
return HTTPNotFound()
bmark.fromdict(post)
bmark.update_tags(post['tags'])
# if this is a new bookmark from a url, offer to go back to that url
# for the user.
if 'go_back' in params and params['comes_from'] != "":
return HTTPFound(location=params['comes_from'])
else:
return HTTPFound(
location=request.route_url('user_bmark_recent',
username=request.user.username))
@view_config(
route_name="bmark_readable",
renderer="/bmark/readable.mako")
def readable(request):
"""Display a readable version of this url if we can"""
rdict = request.matchdict
bid = rdict.get('hash_id', None)
username = rdict.get('username', None)
if username:
username = username.lower()
if bid:
found = BmarkMgr.get_by_hash(bid, username=username)
if found:
return {
'bmark': found,
'username': username,
}
else:
return HTTPNotFound()
@view_config(route_name="user_delete_all_bookmarks",
renderer="/accounts/index.mako")
def delete_all_bookmarks(request):
"""Delete all bookmarks of the current user"""
rdict = request.matchdict
post = request.POST
with ReqAuthorize(request, username=rdict['username'].lower()):
username = request.user.username
if username:
if post['delete'] == 'Delete':
from bookie.bcelery import tasks
tasks.delete_all_bookmarks.delay(username)
return {
'user': request.user,
'message': 'The delete request has been queued' +
' and will be acted upon shortly.',
}
else:
return {
'user': request.user,
'message': 'Delete request not confirmed. ' +
'Please make sure to enter' +
' \'Delete\' to confirm.',
}
else:
return HTTPNotFound()