This repository has been archived by the owner on Mar 19, 2021. It is now read-only.
/
views.py
230 lines (203 loc) · 8.58 KB
/
views.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
import os
import datetime
import urllib
from flask import (flash, redirect, render_template, request,
Response, url_for, jsonify, send_from_directory)
from flask import url_for as flask_url_for
from werkzeug.utils import secure_filename
from playhouse.flask_utils import get_object_or_404, object_list
from playhouse.sqlite_ext import *
from app import application
from models import Entry, Tag, EntryTags
# Make url_for use https when hosted on Sandstorm with SSL
def url_for(endpoint, **kwargs):
if os.getenv('SANDSTORM'):
kwargs.setdefault('_external', True)
if request.headers.get('X-Forwarded-Proto') == "https":
kwargs.setdefault('_scheme', 'https')
else:
kwargs.setdefault('_scheme', 'http')
return flask_url_for(endpoint, **kwargs)
@application.route('/')
def index():
search_query = request.args.get('q')
if search_query:
query = Entry.search(search_query)
else:
query = Entry.public().order_by(Entry.timestamp.desc())
# The `object_list` helper will take a base query and then handle
# paginating the results if there are more than 20. For more info see
# the docs:
# http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#object_list
return object_list(
'index.html',
query,
search=search_query,
check_bounds=False)
@application.route('/archive/')
def archive():
query = Entry.archive().order_by(Entry.timestamp.desc())
return object_list(
'index.html',
query,
archive=archive,
check_bounds=False)
@application.route('/create/', methods=['GET', 'POST'])
def create():
if request.method == 'POST':
if request.form.get('title') and request.form.get('content'):
try:
entry = Entry.create(
title=request.form['title'],
content=request.form['content'],
archived=request.form.get('archived') or False)
tags = request.form['tags'].split()
# present is a check to see if the tag exists
present = 0
# add or create tags
for tag in tags:
for entrytag in entry.tags:
if tag == entrytag.tag:
present = 1
if present == 0:
try:
thistag = Tag.get(Tag.tag == tag)
entry.tags.add(thistag)
except:
tag_obj, was_created = Tag.create_or_get(tag=tag)
EntryTags.create(tag=tag_obj, entry=entry)
present = 0
flash('Entry created successfully.', 'success')
return redirect(url_for('detail', slug=entry.slug))
except:
flash('Note title already exists', 'danger')
return render_template('create.html')
# TODO Refactor the below and above to make it more DRY or not
# to need to display seconds (e.g. add some kind of suffix if entry
# already exists)
elif request.form.get('content'):
entry = Entry.create(
title="{:%a %d %b %Y at %H:%M:%S}".format(datetime.datetime.now()),
content=request.form['content'])
flash('Note created successfully.', 'success')
return redirect(url_for('detail', slug=entry.slug))
else:
flash('Content is required.', 'danger')
return render_template('create.html')
@application.route('/<slug>/')
def detail(slug):
query = Entry.all()
entry = get_object_or_404(query, Entry.slug == slug)
tags = ""
for tag in entry.tags:
tags = tags + " " + tag.tag
return render_template('detail.html', entry=entry, tags=tags)
@application.route('/<slug>/edit/', methods=['GET', 'POST'])
def edit(slug):
entry = get_object_or_404(Entry, Entry.slug == slug)
tags = ""
for tag in entry.tags:
tags = tags + " " + tag.tag
if request.method == 'POST':
if request.form.get('title') and request.form.get('content'):
try:
entry.title = request.form['title']
entry.content = request.form['content']
entry.archived = request.form.get('archived') or False
entry.lastedited = datetime.datetime.now()
# convert the string of tags to a list
tags = request.form['tags'].split()
# present is a check to see if the tag exists
present = 0
# add or create tags
for tag in tags:
for entrytag in entry.tags:
if tag == entrytag.tag:
present = 1
if present == 0:
try:
thistag = Tag.get(Tag.tag == tag)
entry.tags.add(thistag)
except:
tag_obj, was_created = Tag.create_or_get(tag=tag)
EntryTags.create(tag=tag_obj, entry=entry)
present = 0
# remove tags
for entrytag in entry.tags:
for tag in tags:
if entrytag.tag == tag:
present = 1
if present == 0:
thistag = Tag.get(Tag.tag == entrytag.tag)
entry.tags.remove(thistag)
present = 0
entry.save()
flash('Note updated successfully.', 'success')
return redirect(url_for('detail', slug=entry.slug))
except:
flash('Note title already exists', 'danger')
return render_template('create.html')
else:
flash('Title and Content are required.', 'danger')
return render_template('edit.html', entry=entry, tags=tags)
@application.route('/tags/')
def taglist():
count = fn.COUNT(EntryTags.id)
tags_with_counts = (Tag
.select(Tag, count.alias('entry_count'))
.join(EntryTags)
.join(Entry)
.where(Entry.archived==False)
.group_by(Tag)
.order_by(count.desc(), Tag.tag))
return object_list('taglist.html', tags_with_counts, check_bounds=False)
@application.route('/tag/<tag>/')
def thistag(tag):
search_query = request.args.get('q')
query = (Entry.public()
.select()
.join(EntryTags)
.join(Tag)
.where(
(Tag.tag == tag))
.order_by(Entry.timestamp.desc()))
return object_list(
'index.html',
query,
tag=tag,
search=search_query,
check_bounds=False)
@application.route('/upload/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(application.config['UPLOAD_FOLDER'], filename))
filenamedict = dict([("filename", os.path.join('/uploads/', filename))])
else:
filenamedict = dict([("error", "Error while uploading file")])
# see http://stackoverflow.com/a/13089975/94908 for explanation of the below
return jsonify(**filenamedict)
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in application.config['ALLOWED_EXTENSIONS']
@application.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(application.config['UPLOAD_FOLDER'],
filename)
@application.template_filter('clean_querystring')
def clean_querystring(request_args, *keys_to_remove, **new_values):
# We'll use this template filter in the pagination include. This filter
# will take the current URL and allow us to preserve the arguments in the
# querystring while replacing any that we need to overwrite. For instance
# if your URL is /?q=search+query&page=2 and we want to preserve the search
# term but make a link to page 3, this filter will allow us to do that.
querystring = dict((key, value) for key, value in request_args.items())
for key in keys_to_remove:
querystring.pop(key, None)
querystring.update(new_values)
return urllib.urlencode(querystring)
@application.errorhandler(404)
def not_found(exc):
return Response('<h3>Not found</h3>'), 404