Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 264 lines (222 sloc) 8.857 kB
ce81f87 Added 'draft' facility
Nicholas Johnson authored
1 import datetime
d88a783 @Arachnid Added post regeneration code
Arachnid authored
2 import logging
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
3 import os
4
d88a783 @Arachnid Added post regeneration code
Arachnid authored
5 from google.appengine.ext import deferred
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
6 from google.appengine.ext import webapp
7
7b5b638 @Arachnid Added andialbrecht's markup language patch.
Arachnid authored
8 import config
9 import markup
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
10 import models
d88a783 @Arachnid Added post regeneration code
Arachnid authored
11 import post_deploy
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
12 import utils
4ad9b5c @detro Content Regeneration improvements and Admin content pagination fixes.
authored
13 from generators import generator_list
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
14
7c9a0b5 @detro * Explicit declaration of Django '0.96' as required here: http://code…
authored
15 # Bloggart is currently based on Django 0.96
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
16 import os
17 os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
7c9a0b5 @detro * Explicit declaration of Django '0.96' as required here: http://code…
authored
18 from google.appengine.dist import use_library
19 use_library('django', '0.96')
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
20 from django import newforms as forms
21 from google.appengine.ext.db import djangoforms
22
23
24 class PostForm(djangoforms.ModelForm):
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
25 title = forms.CharField(widget=forms.TextInput( attrs={'id':'name'} ));
26 body = forms.CharField(widget=forms.Textarea( attrs={'id':'message', 'rows': 10, 'cols': 20} ));
27 body_markup = forms.ChoiceField( choices=[(k, v[0]) for k, v in markup.MARKUP_MAP.iteritems()] );
28 tags = forms.CharField(widget=forms.Textarea(attrs={'rows': 5, 'cols': 20}));
29 draft = forms.BooleanField(required=False);
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
30 class Meta:
31 model = models.BlogPost
ce81f87 Added 'draft' facility
Nicholas Johnson authored
32 fields = [ 'title', 'body', 'tags' ]
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
33
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
34
35 class PageForm(djangoforms.ModelForm):
36 # Overridden constructor to initialise the Form properly
37 def __init__(self, current_page, *args, **kwargs):
38 self.base_fields['parent_page'].query = models.Page.all();
39 if ( current_page ):
40 # Show all the pages, except the one associated with the current form instance
41 self.base_fields['parent_page'].query.filter("__key__ != ", current_page.key());
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
42
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
43 self.base_fields['parent_page'].widget.choices = self.base_fields['parent_page'].choices;
44 super(PageForm, self).__init__(*args, **kwargs);
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
45
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
46 title = forms.CharField( widget=forms.TextInput( attrs={'id':'name'} ));
47 parent_page = djangoforms.ModelChoiceField( models.Page, None, required=False, initial=None, empty_label="none" );
48 body = forms.CharField( widget=forms.Textarea( attrs={'id':'message', 'rows': 10, 'cols': 20} ));
49 body_markup = forms.ChoiceField( choices=[(k, v[0]) for k, v in markup.MARKUP_MAP.iteritems()] );
50 draft = forms.BooleanField( required=False );
51 class Meta:
52 model = models.Page
53 fields = [ 'title', 'parent_page', 'body' ]
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
54
55
56 def with_post(fun):
57 def decorate(self, post_id=None):
58 post = None
59 if post_id:
60 post = models.BlogPost.get_by_id(int(post_id))
61 if not post:
62 self.error(404)
63 return
64 fun(self, post)
65 return decorate
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
66
5f3dcfa @detro Almost done introducing support for Pages
authored
67
68 def with_page(fun):
69 def decorate(self, page_id=None):
70 page = None
71 if page_id:
72 page = models.Page.get_by_id(int(page_id));
73 if not page:
74 self.error(404);
75 return
76 fun(self, page)
77 return decorate;
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
78
79
80 class BaseHandler(webapp.RequestHandler):
81 def render_to_response(self, template_name, template_vals=None, theme=None):
c8d437d @Arachnid Added menu items on admin pages. Fixes #6.
Arachnid authored
82 if not template_vals:
83 template_vals = {}
84 template_vals.update({
239d8de @Arachnid Fixed erroneous highlighting of 'new post' tab in admin console
Arachnid authored
85 'path': self.request.path,
c8d437d @Arachnid Added menu items on admin pages. Fixes #6.
Arachnid authored
86 'handler_class': self.__class__.__name__,
12d9f88 @rctay handlers: don't show analytics for *all* admin pages
rctay authored
87 'is_admin': True,
c8d437d @Arachnid Added menu items on admin pages. Fixes #6.
Arachnid authored
88 })
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
89 template_name = os.path.join("admin", template_name)
90 self.response.out.write(utils.render_template(template_name, template_vals,
91 theme))
92
93
94 class AdminHandler(BaseHandler):
95 def get(self):
4ad9b5c @detro Content Regeneration improvements and Admin content pagination fixes.
authored
96 # Entry per page
97 entry_per_page = 10
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
98
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
99 posts_offset = int(self.request.get('posts_start', 0));
4ad9b5c @detro Content Regeneration improvements and Admin content pagination fixes.
authored
100 posts_count = int(self.request.get('posts_count', entry_per_page));
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
101 posts = models.BlogPost.all().order('-published').fetch(posts_count, posts_offset);
102 pages_offset = int(self.request.get('pages_start', 0));
4ad9b5c @detro Content Regeneration improvements and Admin content pagination fixes.
authored
103 pages_count = int(self.request.get('pages_count', entry_per_page));
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
104 pages = models.Page.all().order('-published').fetch(pages_count, pages_offset);
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
105 template_vals = {
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
106 'posts_offset': posts_offset,
107 'posts_count': posts_count,
108 'posts_last_post': posts_offset + len(posts) - 1,
109 'posts_prev_offset': max(0, posts_offset - posts_count),
110 'posts_next_offset': posts_offset + posts_count,
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
111 'posts': posts,
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
112 'pages_offset': pages_offset,
113 'pages_count': pages_count,
114 'pages_last_page': pages_offset + len(pages) - 1,
115 'pages_prev_offset': max(0, pages_offset - pages_count),
116 'pages_next_offset': pages_offset + pages_count,
117 'pages': pages,
8c672ef @rctay allow selection of content generators
rctay authored
118 'generators': [cls.__name__ for cls in generator_list],
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
119 };
120 self.render_to_response("index.html", template_vals);
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
121
122
123 class PostHandler(BaseHandler):
124 def render_form(self, form):
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
125 self.render_to_response("edit_post.html", {'form': form})
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
126
127 @with_post
128 def get(self, post):
ce81f87 Added 'draft' facility
Nicholas Johnson authored
129 self.render_form(PostForm(
130 instance=post,
7b5b638 @Arachnid Added andialbrecht's markup language patch.
Arachnid authored
131 initial={
9d6190f @Arachnid Fixed draft behaviour
Arachnid authored
132 'draft': post and not post.path,
7b5b638 @Arachnid Added andialbrecht's markup language patch.
Arachnid authored
133 'body_markup': post and post.body_markup or config.default_markup,
134 }))
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
135
136 @with_post
137 def post(self, post):
ce81f87 Added 'draft' facility
Nicholas Johnson authored
138 form = PostForm(data=self.request.POST, instance=post,
139 initial={'draft': post and post.published is None})
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
140 if form.is_valid():
141 post = form.save(commit=False)
01f6e97 @detro BUGFIX: Post/Page editing doesn't always regenerate the static content.
authored
142 if form.clean_data['draft']:
143 # Post is marked as DRAFT
9d6190f @Arachnid Fixed draft behaviour
Arachnid authored
144 post.published = datetime.datetime.max
ce81f87 Added 'draft' facility
Nicholas Johnson authored
145 post.put()
146 else:
01f6e97 @detro BUGFIX: Post/Page editing doesn't always regenerate the static content.
authored
147 # Post is NOT marked as DRAFT - hence, PUBLISH
148 if not post.path:
149 # Just published
e3db25a @rctay enforce timezone in datetime.datetime.now()
rctay authored
150 post.updated = post.published = datetime.datetime.now(utils.tzinfo())
01f6e97 @detro BUGFIX: Post/Page editing doesn't always regenerate the static content.
authored
151 else:
152 # Edited
e3db25a @rctay enforce timezone in datetime.datetime.now()
rctay authored
153 post.updated = datetime.datetime.now(utils.tzinfo())
01f6e97 @detro BUGFIX: Post/Page editing doesn't always regenerate the static content.
authored
154
155 post.put()
ce81f87 Added 'draft' facility
Nicholas Johnson authored
156 post.publish()
01f6e97 @detro BUGFIX: Post/Page editing doesn't always regenerate the static content.
authored
157
ce81f87 Added 'draft' facility
Nicholas Johnson authored
158 self.render_to_response("published.html", {
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
159 'content': post,
160 'type' : 'post',
ce81f87 Added 'draft' facility
Nicholas Johnson authored
161 'draft': form.clean_data['draft']})
c94ebfe Refactored admin code into separate modules
Nicholas Johnson authored
162 else:
163 self.render_form(form)
d88a783 @Arachnid Added post regeneration code
Arachnid authored
164
5f3dcfa @detro Almost done introducing support for Pages
authored
165 class DeletePostHandler(BaseHandler):
6b415b5 Added post/draft delete option to the admin index page.
Jai Sharma authored
166 @with_post
167 def post(self, post):
5f3dcfa @detro Almost done introducing support for Pages
authored
168 # TODO
169 if post.path: # Published post
170 post.remove();
171 else: # Draft
172 post.delete();
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
173 self.render_to_response("deleted.html", {'type' : 'post'});
d88a783 @Arachnid Added post regeneration code
Arachnid authored
174
7580537 @andialbrecht Add preview page for drafts.
andialbrecht authored
175
5f3dcfa @detro Almost done introducing support for Pages
authored
176 class PreviewPostHandler(BaseHandler):
7580537 @andialbrecht Add preview page for drafts.
andialbrecht authored
177 @with_post
178 def get(self, post):
179 # Temporary set a published date iff it's still
180 # datetime.max. Django's date filter has a problem with
181 # datetime.max and a "real" date looks better.
182 if post.published == datetime.datetime.max:
5f3dcfa @detro Almost done introducing support for Pages
authored
183 post.published = datetime.datetime.now(utils.tzinfo());
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
184 self.response.out.write(utils.render_template('post.html', {'post' : post, 'is_admin' : True}));
5f3dcfa @detro Almost done introducing support for Pages
authored
185
186
187 class PageHandler(BaseHandler):
188 def render_form(self, form):
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
189 self.render_to_response("edit_page.html", {'form': form})
5f3dcfa @detro Almost done introducing support for Pages
authored
190
191 @with_page
192 def get(self, page):
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
193 self.render_form(PageForm(instance=page,
194 current_page=page,
195 initial={
196 'draft': page and not page.path,
197 'body_markup': page and page.body_markup or config.default_markup
198 }));
5f3dcfa @detro Almost done introducing support for Pages
authored
199
200 @with_page
201 def post(self, page):
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
202 form = PageForm(current_page=page, data=self.request.POST, instance=page, initial={'draft': page and page.published is None});
5f3dcfa @detro Almost done introducing support for Pages
authored
203 if form.is_valid():
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
204 page = form.save(commit=False);
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
205
2e927fb @detro * Added "Breadcrumb Pages" and "Child Pages" support
authored
206 # Ensure that a 'Child Page' is never assigned as 'Parent Page' as well
e67a483 @detro Minor fixes.
authored
207 page.put();
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
208 for p in page.child_pages:
2e927fb @detro * Added "Breadcrumb Pages" and "Child Pages" support
authored
209 if page.parent_page and page.parent_page.key() == p.key():
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
210 page.parent_page = None;
211 page.put();
212 break;
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
213
01f6e97 @detro BUGFIX: Post/Page editing doesn't always regenerate the static content.
authored
214 if form.clean_data['draft']:
215 # Page is marked as DRAFT
216 page.published = datetime.datetime.max
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
217 page.put();
5f3dcfa @detro Almost done introducing support for Pages
authored
218 else:
01f6e97 @detro BUGFIX: Post/Page editing doesn't always regenerate the static content.
authored
219 # Page is NOT marked as DRAFT - hence, PUBLISH
220 if not page.path:
221 # Just published
222 page.updated = page.published = datetime.datetime.now(utils.tzinfo())
223 else:
224 # Edited
225 page.updated = datetime.datetime.now(utils.tzinfo())
226
227 page.put()
228 page.publish()
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
229 self.render_to_response("published.html", {'content': page, 'type' : 'page', 'draft': form.clean_data['draft']});
5f3dcfa @detro Almost done introducing support for Pages
authored
230 else:
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
231 self.render_form(form);
5f3dcfa @detro Almost done introducing support for Pages
authored
232
233 class DeletePageHandler(BaseHandler):
234 @with_page
235 def post(self, page):
30cf4f9 @detro Modification to the "Squared" template to highlight top_pages nav bar…
authored
236 if page.path: # Published page
5f3dcfa @detro Almost done introducing support for Pages
authored
237 page.remove();
238 else: # Draft
239 page.delete();
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
240 self.render_to_response("deleted.html", {'type' : 'page'});
5f3dcfa @detro Almost done introducing support for Pages
authored
241
242
243 class PreviewPageHandler(BaseHandler):
244 @with_page
245 def get(self, page):
246 # Temporary set a published date iff it's still
247 # datetime.max. Django's date filter has a problem with
248 # datetime.max and a "real" date looks better.
249 if page.published == datetime.datetime.max:
250 page.published = datetime.datetime.now(utils.tzinfo());
bb870cc @detro This is the first version of Bloggart with support for Pages!
authored
251 self.response.out.write(utils.render_template('page.html', {'page' : page, 'is_admin' : True}));
5f3dcfa @detro Almost done introducing support for Pages
authored
252
7580537 @andialbrecht Add preview page for drafts.
andialbrecht authored
253
d88a783 @Arachnid Added post regeneration code
Arachnid authored
254 class RegenerateHandler(BaseHandler):
255 def post(self):
4ad9b5c @detro Content Regeneration improvements and Admin content pagination fixes.
authored
256 # Force the regeneration of all the content
257 post_deploy.regenerate_all(force=True)
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
258
4ad9b5c @detro Content Regeneration improvements and Admin content pagination fixes.
authored
259 # Post-Deploy tasks (i.e. regenerate static pages)
486024f @detro Implemented Page Regeneration.
authored
260 deferred.defer(post_deploy.try_post_deploy, force=True);
8c672ef @rctay allow selection of content generators
rctay authored
261
5db3874 @detro Ensuring we declare which version of Django (0.96) to use.
authored
262 # Render a "regenerating" page
d88a783 @Arachnid Added post regeneration code
Arachnid authored
263 self.render_to_response("regenerating.html")
Something went wrong with that request. Please try again.