Dynastie

Dynastie Commit Details

Date:2016-01-09 20:10:27 (4 years 6 months ago)
Author:Grégory Soutadé
Branch:master
Commit:e0b8f544ffdc1905da4348572218c5d233e37cfb
Parents: 9b49bf91142f40bf76e918ed5a31c88c662c34ba
Message:

Fix HTML article inclusion Fix draft inclusion in preview Enhance cache post content (avoid recomputing md5sum if present) Add generation duration time Add post only generation (for Dev) Remove Draft when it becomes Post Update blog Copyright Update TinyMCE plugins for inclusion Sort tags by name
Changes:
MChangeLog (1 diff)
MREADME (2 diffs)
Mdynastie/generators/generator.py (1 diff)
Mdynastie/generators/index.py (8 diffs)
Mdynastie/generators/post.py (3 diffs)
Mdynastie/models.py (3 diffs)
Mdynastie/sites/blog.soutade.fr/_base.html (2 diffs)
Mdynastie/sites/blog.soutade.fr/_base_post.html (2 diffs)
Mdynastie/sites/blog.soutade.fr/css/blog.css (2 diffs)
Mdynastie/static/js/dynastie.js (3 diffs)
Mdynastie/templates/view_blog.html (1 diff)
Mdynastie/urls.py (1 diff)
Mdynastie/views.py (8 diffs)

File differences

ChangeLog
1
1
22
33
44
55
66
77
8
9
10
11
12
13
14
815
916
1017
11
18
1219
1320
1421
v0.4 (08/11/2015)
v0.4 (09/01/2016)
** User **
Redirect user to comment when it's added and not to begining of page
Enable code coloration support with Markdown syntax
Add article inclusion
Add autofocus to login page
Sort tags by name
Add generation duration time
** Dev **
Support Django 1.8
Enhance cache post content (avoid recomputing md5sum if present)
Add post only generation (for Dev)
** Bugs **
Always update modification date when post/draft is saved
Support Django 1.8
Draft were not remove from _draft directory when moving to Post
v0.3 (13/11/2014)
README
11
22
3
3
44
55
66
......
1010
1111
1212
13
13
1414
1515
1616
Dynastie is static blog generator delivered under GPL v3 licence terms.
Current version is 0.5
Current version is 0.4
Requirements :
Django >= 1.8, libapache2-mod-wsgi if you want to use Dynastie with Apache. PyGments (Optional).
* Update dynastie/wsgy.py (with $PWD/../) don't forget the final slash !
* Update dynastie/settings.py (SECRET_KEY...)
* Run ./manage.sh syncdb and create a superuser
* Run ./manage.sh runserver
* Run ./manage.sh runserver 0.0.0.0:8080
or
* Copy (and edit) apache_dynastie.conf in /etc/apache2/sites-available, and create a symbolic link from /etc/apache2/sites-enabled to /etc/apache2/sites-available
dynastie/generators/generator.py
5757
5858
5959
60
60
6161
6262
63
6364
6465
66
6567
6668
6769
URI = "http://indefero.soutade.fr/p/dynastie"
def __init__(self, hash_posts={}, hash_posts_content={}):
def __init__(self, request, hash_posts={}, hash_posts_content={}):
self.report = ''
self.somethingWrote = False
self.request = request
self.hash_posts = hash_posts
self.hash_posts_content = hash_posts_content
self.user = request and request.user or None
def addReport(self, string, color=''):
if string in self.report: return
dynastie/generators/index.py
3131
3232
3333
34
35
34
35
3636
3737
3838
......
5353
5454
5555
56
5657
5758
5859
......
143144
144145
145146
146
147
148
147149
148150
149151
......
230232
231233
232234
233
235
234236
235237
236
237
238
239
240
241
242
243
244
245
246
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
247271
248272
249
273
250274
251275
252276
......
255279
256280
257281
258
259
282
283
284
285
286
287
260288
261289
262290
263291
264292
293
294
265295
266
267
268296
269297
270298
271299
272300
273301
274
302
275303
276304
277305
278306
279307
280
308
281309
282310
283311
......
286314
287315
288316
289
317
318
290319
291320
292321
......
302331
303332
304333
334
335
336
337
338
339
340
305341
306342
307343
308344
309345
310
311
312
313
314
315
316
317
346
318347
319
320
321
322
323
324
325348
326
349
327350
328
351
329352
330
353
331354
332355
333356
......
544567
545568
546569
570
547571
548572
549573
class Index(DynastieGenerator):
def __init__(self, hash_posts={}, hash_posts_content={}):
DynastieGenerator.__init__(self, hash_posts, hash_posts_content)
def __init__(self, request=None, hash_posts={}, hash_posts_content={}):
DynastieGenerator.__init__(self, request, hash_posts, hash_posts_content)
self.hooks = {'posts' : self.createPosts,
'title' : self.createTitle,
self.filename = 'index'
self.dirname = ''
self.blog = None
self.parent_posts = []
self.resetCounters()
nav = nav + href + str(self.cur_page+1) + '.html">Next &gt;</a> '
nav = nav + href + str(self.nb_pages-1) + '.html">Last &gt;&gt;</a>'
new_dom = parseString('<div class="navigation">' + nav + '</div>')
s = '<div class="navigation">' + nav + '</div>'
new_dom = parseString(s.encode('utf-8'))
new_node = new_dom.getElementsByTagName('div')[0]
res = new_node.cloneNode(True)
root.replaceChild(res, node)
return (b, p)
def _manageInternalPosts(self, post, text, parent_posts, user=None):
def _manageInternalPosts(self, post, text, user=None):
from dynastie.models import Post
if not user: user = post.author
if post and post.content_format != Post.CONTENT_TEXT: return text
internal_posts = re.search('\[\[([0-9]+)\]\]', text)
if not internal_posts: return text
for post_id in internal_posts.groups():
post_id = int(post_id)
if post_id in parent_posts: continue
_,post = self._have_I_right(user, post_id)
if not post: continue
new_content = self._loadPostContent(post, parent_posts)
if new_content:
text = text.replace('[[' + str(post_id) + ']]', new_content)
# Markdown replace
if not post or (post and post.content_format == Post.CONTENT_TEXT):
internal_posts = re.search('\[\[([0-9]+)\]\]', text)
if internal_posts:
for post_id in internal_posts.groups():
post_id = int(post_id)
if post_id in self.parent_posts: continue
_,post = self._have_I_right(user, post_id)
if not post: continue
new_content = self._loadPostContent(post)
if new_content:
text = text.replace('[[' + str(post_id) + ']]', new_content)
if internal_posts: return text
# HTML replace
if not post or (post and post.content_format == Post.CONTENT_HTML):
while True:
start = text.find('<dyn:postinclude')
if start == -1: break
end = text.find('</dyn:postinclude>')
if end < start:
self.addError('Invalid <dyn:postinclude> tags in ' + self.filename)
break
internal_posts = re.search('post_id="([0-9]+)"', text[start:])
if not internal_posts: break
for post_id in internal_posts.groups():
_,post = self._have_I_right(user, post_id)
if not post: break
new_content = self._loadPostContent(post)
if new_content:
text = text.replace(text[start:end+18], new_content.encode('utf-8'))
return text
def _loadPostContent(self, post, parent_posts):
def _loadPostContent(self, post):
from dynastie.models import Post
blog = post.blog
filename = blog.src_path + '/_post/' + str(post.id)
if not os.path.exists(filename):
self.addError('File does not exists ' + filename)
return None
filename2 = blog.src_path + '/_draft/' + str(post.id)
if not os.path.exists(filename2):
self.addError('File does not exists ' + filename)
return None
else:
filename = filename2
if not filename in self.hash_posts_content:
f = open(filename, 'rb')
post_content = f.read()
f.close()
self.parent_posts.append(post.id)
post_content = self._manageInternalPosts(post, post_content)
if post.content_format == Post.CONTENT_TEXT:
parent_posts.append(post.id)
post_content = self._manageInternalPosts(post, post_content, parent_posts)
post_content = markdown2.markdown(post_content, extras=['fenced-code-blocks'])
self.hash_posts_content[filename] = post_content
else:
post_content = self.hash_posts_content[filename]
return post_content
def createPost(self, posts, dom, post_elem, root):
from dynastie.models import Post
post = self.cur_post_obj
if post.id in self.hash_posts and not self.first_try:
node = self.hash_posts[post.id]
node,_ = self.hash_posts[post.id]
return node.cloneNode(0)
values = {'post_content': '', 'author': 'Unknown'}
except:
pass
post_content = _loadPostContent(post, [])
self.parent_posts = []
post_content = self._loadPostContent(post)
if not post_content: return None
post_content = self.pygmentCode(post_content)
new_node = dom.createTextNode(post_content)
content_node.appendChild(new_node)
writer = StrictUTF8Writer()
post_elem.writexml(writer)
content = writer.getvalue().encode('utf-8')
md5 = hashlib.md5()
md5.update(content)
if post.id in self.hash_posts:
# Here, we are in first_try, check that computed
# post has the same result than the one in cache
self.first_try = False
writer = StrictUTF8Writer()
node = self.hash_posts[post.id]
node.writexml(writer)
content1 = writer.getvalue().encode('utf-8')
writer = StrictUTF8Writer()
post_elem.writexml(writer)
content2 = writer.getvalue().encode('utf-8')
_,md5_2 = self.hash_posts[post.id]
md5_1 = hashlib.md5()
md5_1.update(content1)
md5_2 = hashlib.md5()
md5_2.update(content2)
# If not, clear cache
if md5_1.digest() != md5_2.digest():
if md5.digest() != md5_2:
self.hash_posts = {}
self.hash_posts[post.id] = post_elem.cloneNode(0)
self.hash_posts[post.id] = (post_elem.cloneNode(0), md5.digest())
else:
self.hash_posts[post.id] = post_elem.cloneNode(0)
self.hash_posts[post.id] = (post_elem.cloneNode(0), md5.digest())
return post_elem
from dynastie.models import Post, Blog
self.blog = blog
self.parent_posts = []
dom = self.parseTemplate(blog, src, output, 'index')
if dom is None: return self.report
dynastie/generators/post.py
217217
218218
219219
220
220221
221222
222223
......
230231
231232
232233
233
234
234235
235236
236237
237238
238239
239240
241
240242
241243
242244
243245
244246
245
246
247
248
249
250
251
247252
248253
249254
250255
251256
252
257
253258
254259
255260
......
258263
259264
260265
261
266
267
262268
263269
264270
self.blog = blog
self.parent_posts = []
posts = Post.objects.all()
return self._generate(blog, src, output, posts)
v['date'] = now.strftime("%A, %d %B %Y %H:%m")
v['post_content'] = ''
post_content = self._manageInternalPosts(None, values['content'], [], self.user)
post_content = self._manageInternalPosts(None, values['content'], self.user)
post_content = self.pygmentCode(post_content)
self.simpleTransform(v, dom, root, node)
content_nodes = root.getElementsByTagName("div")
post_transform = ('post_content')
content_node = None
for content_node in content_nodes:
the_class = content_node.getAttribute('class')
if not the_class in post_transform:
continue
if the_class == 'post_content':
new_node = dom.createTextNode(post_content)
content_node.appendChild(new_node)
s = u'<div>' + post_content + u'</div>'
new_node = parseString(s.encode('utf-8'))
for n in new_node.childNodes[0].childNodes:
content_node.appendChild(n)
break
post_nodes = dom.getElementsByTagNameNS(self.URI, "post")
post_elem = post_nodes[0]
post_elem.parentNode.removeChild(post_elem)
return post_elem
return content_node
def preview(self, request, src, values):
from dynastie.models import Blog
# Override all hooks
self.hooks = {'post' : self.createPreview,
'tags' : self.createTags}
'tags' : self.createTags,
}
if not os.path.exists(src + '/_post.html'):
self.addError('No _post.html found, exiting')
dynastie/models.py
171171
172172
173173
174
175
174
175
176
176177
177178
178179
......
190191
191192
192193
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
194221
195222
196223
......
443470
444471
445472
473
474
475
476
446477
447478
448479
if errors:
raise Exception(errors)
def generate(self):
self.report = '<br/><br/>Generation of ' + datetime.now().strftime("%d/%m/%Y at %H:%M:%S") + '<br/>\n'
def generate(self, request):
start_time = datetime.now()
self.report = ''
self.load_generators()
self.copytree(self.src_path, self.output_path)
generated = []
if not r is None:
self.report = self.report + '<br/>\n' + r
return self.report
duration = datetime.now() - start_time
t = '<br/><br/>Generation of ' + start_time.strftime("%d/%m/%Y at %H:%M:%S") + '<br/>\n'
t = t + 'Duration ' + str(duration) + '<br/><br/>\n'
return t + self.report
def generate_post(self, request, post):
from dynastie.generators import post as PostGenerator
start_time = datetime.now()
self.report = ''
self.load_generators()
self.copytree(self.src_path, self.output_path)
post_list = [post]
hash_posts = {}
hash_posts_content = {}
engine = globals()['post']
for name, obj in inspect.getmembers(engine):
if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \
and obj.__module__.endswith("post"):
e = obj(request, hash_posts, hash_posts_content)
self.report = e._generate(self, self.src_path, self.output_path, post_list)
break
# report = PostGenerator()._generate(self, self.src_path, self.output_path, post_list)
duration = datetime.now() - start_time
t = '<br/><br/>Generation of ' + start_time.strftime("%d/%m/%Y at %H:%M:%S") + ' post ' + str(post.id) + '<br/>\n'
t = t + 'Duration ' + str(duration) + '<br/><br/>\n'
return t + self.report
class Editor(models.Model):
name = models.CharField(max_length=255, unique=True)
def delete_post_signal(sender, **kwargs):
kwargs['instance'].remove()
@receiver(post_delete, sender=Draft)
def delete_draft_signal(sender, **kwargs):
kwargs['instance'].remove()
@receiver(pre_delete, sender=Post)
def pre_delete_post_signal(sender, **kwargs):
post = kwargs['instance']
dynastie/sites/blog.soutade.fr/_base.html
7777
7878
7979
80
8081
8182
8283
......
9495
9596
9697
97
98
9899
99100
100101
<div class="menu_content_header">Archives</div>
<div class="menu_content_content">
<ul>
<li><a href="/archive/2015">2015</a></li>
<li><a href="/archive/2014">2014</a></li>
<li><a href="/archive/2013">2013</a></li>
<li><a href="/archive/2012">2012</a></li>
</div>
<footer>
<div class="footer">
Copyright © 2010-2015 Grégory Soutadé.<br/>
Copyright © 2010-2016 Grégory Soutadé.<br/>
Tous droits réservés.
</div>
</footer>
dynastie/sites/blog.soutade.fr/_base_post.html
7878
7979
8080
81
8182
8283
8384
......
9596
9697
9798
98
99
99100
100101
101102
<div class="menu_content_header">Archives</div>
<div class="menu_content_content">
<ul>
<li><a href="/archive/2015">2015</a></li>
<li><a href="/archive/2014">2014</a></li>
<li><a href="/archive/2013">2013</a></li>
<li><a href="/archive/2012">2012</a></li>
</div>
<footer>
<div class="footer">
Copyright © 2010-2015 Grégory Soutadé.<br/>
Copyright © 2010-2016 Grégory Soutadé.<br/>
Tous droits réservés.
</div>
</footer>
dynastie/sites/blog.soutade.fr/css/blog.css
341341
342342
343343
344
344
345345
346346
347347
348348
349349
350
350
351351
352352
353353
......
463463
464464
465465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528528
529529
530530
.inlineimage
{
display:inline;
margin-right: 50px;
margin-right: 20px;
}
a .inlineimage
{
display:inline;
margin-right: 50px;
margin-right: 20px;
}
h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
}
/* Pygments */
.highlight { background-color: #e8e8e8; }
.color_emacs_hll { background-color: #ffffcc }
.color_emacs_c { color: #008800; font-style: italic } /* Comment */
.color_emacs_err { border: 1px solid #FF0000 } /* Error */
.color_emacs_k { color: #AA22FF; font-weight: bold } /* Keyword */
.color_emacs_o { color: #666666 } /* Operator */
.color_emacs_cm { color: #008800; font-style: italic } /* Comment.Multiline */
.color_emacs_cp { color: #008800 } /* Comment.Preproc */
.color_emacs_c1 { color: #008800; font-style: italic } /* Comment.Single */
.color_emacs_cs { color: #008800; font-weight: bold } /* Comment.Special */
.color_emacs_gd { color: #A00000 } /* Generic.Deleted */
.color_emacs_ge { font-style: italic } /* Generic.Emph */
.color_emacs_gr { color: #FF0000 } /* Generic.Error */
.color_emacs_gh { color: #000080; font-weight: bold } /* Generic.Heading */
.color_emacs_gi { color: #00A000 } /* Generic.Inserted */
.color_emacs_go { color: #808080 } /* Generic.Output */
.color_emacs_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.color_emacs_gs { font-weight: bold } /* Generic.Strong */
.color_emacs_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.color_emacs_gt { color: #0040D0 } /* Generic.Traceback */
.color_emacs_kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */
.color_emacs_kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */
.color_emacs_kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */
.color_emacs_kp { color: #AA22FF } /* Keyword.Pseudo */
.color_emacs_kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */
.color_emacs_kt { color: #00BB00; font-weight: bold } /* Keyword.Type */
.color_emacs_m { color: #666666 } /* Literal.Number */
.color_emacs_s { color: #BB4444 } /* Literal.String */
.color_emacs_na { color: #BB4444 } /* Name.Attribute */
.color_emacs_nb { color: #AA22FF } /* Name.Builtin */
.color_emacs_nc { color: #0000FF } /* Name.Class */
.color_emacs_no { color: #880000 } /* Name.Constant */
.color_emacs_nd { color: #AA22FF } /* Name.Decorator */
.color_emacs_ni { color: #999999; font-weight: bold } /* Name.Entity */
.color_emacs_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.color_emacs_nf { color: #00A000 } /* Name.Function */
.color_emacs_nl { color: #A0A000 } /* Name.Label */
.color_emacs_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.color_emacs_nt { color: #008000; font-weight: bold } /* Name.Tag */
.color_emacs_nv { color: #B8860B } /* Name.Variable */
.color_emacs_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.color_emacs_w { color: #bbbbbb } /* Text.Whitespace */
.color_emacs_mf { color: #666666 } /* Literal.Number.Float */
.color_emacs_mh { color: #666666 } /* Literal.Number.Hex */
.color_emacs_mi { color: #666666 } /* Literal.Number.Integer */
.color_emacs_mo { color: #666666 } /* Literal.Number.Oct */
.color_emacs_sb { color: #BB4444 } /* Literal.String.Backtick */
.color_emacs_sc { color: #BB4444 } /* Literal.String.Char */
.color_emacs_sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */
.color_emacs_s2 { color: #BB4444 } /* Literal.String.Double */
.color_emacs_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.color_emacs_sh { color: #BB4444 } /* Literal.String.Heredoc */
.color_emacs_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.color_emacs_sx { color: #008000 } /* Literal.String.Other */
.color_emacs_sr { color: #BB6688 } /* Literal.String.Regex */
.color_emacs_s1 { color: #BB4444 } /* Literal.String.Single */
.color_emacs_ss { color: #B8860B } /* Literal.String.Symbol */
.color_emacs_bp { color: #AA22FF } /* Name.Builtin.Pseudo */
.color_emacs_vc { color: #B8860B } /* Name.Variable.Class */
.color_emacs_vg { color: #B8860B } /* Name.Variable.Global */
.color_emacs_vi { color: #B8860B } /* Name.Variable.Instance */
.color_emacs_il { color: #666666 } /* Literal.Number.Integer.Long */
.codehilite, .highlight { background-color: #e8e8e8; }
.hl, .color_emacs_hll { background-color: #ffffcc }
.c, .color_emacs_c { color: #008800; font-style: italic } /* Comment */
.er, .color_emacs_err { border: 1px solid #FF0000 } /* Error */
.k, .color_emacs_k { color: #AA22FF; font-weight: bold } /* Keyword */
.o, .color_emacs_o { color: #666666 } /* Operator */
.cm, .color_emacs_cm { color: #008800; font-style: italic } /* Comment.Multiline */
.cp, .color_emacs_cp { color: #008800 } /* Comment.Preproc */
.c1, .color_emacs_c1 { color: #008800; font-style: italic } /* Comment.Single */
.cs, .color_emacs_cs { color: #008800; font-weight: bold } /* Comment.Special */
.gd, .color_emacs_gd { color: #A00000 } /* Generic.Deleted */
.ge, .color_emacs_ge { font-style: italic } /* Generic.Emph */
.gr, .color_emacs_gr { color: #FF0000 } /* Generic.Error */
.gh, .color_emacs_gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi, .color_emacs_gi { color: #00A000 } /* Generic.Inserted */
.go, .color_emacs_go { color: #808080 } /* Generic.Output */
.gp, .color_emacs_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.gs, .color_emacs_gs { font-weight: bold } /* Generic.Strong */
.gu, .color_emacs_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt, .color_emacs_gt { color: #0040D0 } /* Generic.Traceback */
.kc, .color_emacs_kc { color: #AA22FF; font-weight: bold } /* Keyword.Constant */
.kd, .color_emacs_kd { color: #AA22FF; font-weight: bold } /* Keyword.Declaration */
.kn, .color_emacs_kn { color: #AA22FF; font-weight: bold } /* Keyword.Namespace */
.kp, .color_emacs_kp { color: #AA22FF } /* Keyword.Pseudo */
.kr, .color_emacs_kr { color: #AA22FF; font-weight: bold } /* Keyword.Reserved */
.kt, .color_emacs_kt { color: #00BB00; font-weight: bold } /* Keyword.Type */
.m, .color_emacs_m { color: #666666 } /* Literal.Number */
.s, .color_emacs_s { color: #BB4444 } /* Literal.String */
.na, .color_emacs_na { color: #BB4444 } /* Name.Attribute */
.nb, .color_emacs_nb { color: #AA22FF } /* Name.Builtin */
.nc, .color_emacs_nc { color: #0000FF } /* Name.Class */
.no, .color_emacs_no { color: #880000 } /* Name.Constant */
.nd, .color_emacs_nd { color: #AA22FF } /* Name.Decorator */
.ni, .color_emacs_ni { color: #999999; font-weight: bold } /* Name.Entity */
.ne, .color_emacs_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.nf, .color_emacs_nf { color: #00A000 } /* Name.Function */
.nl, .color_emacs_nl { color: #A0A000 } /* Name.Label */
.nn, .color_emacs_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.nt, .color_emacs_nt { color: #008000; font-weight: bold } /* Name.Tag */
.nv, .color_emacs_nv { color: #B8860B } /* Name.Variable */
.ow, .color_emacs_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.w, .color_emacs_w { color: #bbbbbb } /* Text.Whitespace */
.mf, .color_emacs_mf { color: #666666 } /* Literal.Number.Float */
.mh, .color_emacs_mh { color: #666666 } /* Literal.Number.Hex */
.mi, .color_emacs_mi { color: #666666 } /* Literal.Number.Integer */
.mo, .color_emacs_mo { color: #666666 } /* Literal.Number.Oct */
.sb, .color_emacs_sb { color: #BB4444 } /* Literal.String.Backtick */
.sc, .color_emacs_sc { color: #BB4444 } /* Literal.String.Char */
.sd, .color_emacs_sd { color: #BB4444; font-style: italic } /* Literal.String.Doc */
.s2, .color_emacs_s2 { color: #BB4444 } /* Literal.String.Double */
.se, .color_emacs_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.sh, .color_emacs_sh { color: #BB4444 } /* Literal.String.Heredoc */
.si, .color_emacs_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.sx, .color_emacs_sx { color: #008000 } /* Literal.String.Other */
.sr, .color_emacs_sr { color: #BB6688 } /* Literal.String.Regex */
.s1, .color_emacs_s1 { color: #BB4444 } /* Literal.String.Single */
.ss, .color_emacs_ss { color: #B8860B } /* Literal.String.Symbol */
.bp, .color_emacs_bp { color: #AA22FF } /* Name.Builtin.Pseudo */
.vc, .color_emacs_vc { color: #B8860B } /* Name.Variable.Class */
.vg, .color_emacs_vg { color: #B8860B } /* Name.Variable.Global */
.vi, .color_emacs_vi { color: #B8860B } /* Name.Variable.Instance */
.il, .color_emacs_il { color: #666666 } /* Literal.Number.Integer.Long */
#search_form
{
dynastie/static/js/dynastie.js
33
44
55
6
6
77
88
99
......
1414
1515
1616
17
17
1818
1919
2020
......
8585
8686
8787
88
88
// General options
mode : "textareas",
theme : "advanced",
plugins : "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,dynastiecolor",
plugins : "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,dynastiecolor,dynastieinclude",
editor_selector : "mceAdvanced",
encoding : "raw",
entities : "",
// Theme options
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,formatselect,fontselect,fontsizeselect",
theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,charmap,emotions,iespell,media,advhr,dynastiecolor",
theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,charmap,emotions,iespell,media,advhr,dynastiecolor,dynastieinclude",
// theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
help.style.display="block";
// tinymce.execCommand('mceToggleEditor',false,'content');
}
}
}
dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js
1
editor_plugin_src.js
dynastie/templates/view_blog.html
2323
2424
2525
26
26
2727
2828
2929
<b>Drafts</b>
<table>
{% for draft in drafts %}
<tr><td><a href="/draft/edit/{{ draft.id }}">{{ draft.id }}</a></td><td>{{ draft.title }}</td><td>{{ draft.creation_date }}</td><td>{{ draft.modification_date }}</td><td><a href="/draft/delete/{{ draft.id }}" onclick="return confirm('Do you really want to delete this item ?')">Delete</a></td></tr>
<tr><td><a href="/draft/edit/{{ draft.id }}">{{ draft.id }}</a></td><td>{{ draft.title }}</td><td>{{ draft.category.name }}</td><td>{{ draft.creation_date }}</td><td>{{ draft.modification_date }}</td><td><a href="/draft/delete/{{ draft.id }}" onclick="return confirm('Do you really want to delete this item ?')">Delete</a></td></tr>
{% endfor %}
</table><br/>
{% endif %}
dynastie/urls.py
4747
4848
4949
50
5051
5152
5253
url(r'^draft/edit/(\d+)$', 'dynastie.views.edit_draft', name='edit_draft'),
url(r'^draft/delete/(\d+)$', 'dynastie.views.delete_draft', name='delete_draft'),
url(r'^generate/(\d+)$', 'dynastie.views.generate', name='generate'),
url(r'^generate/(\d+)/(\d+)$','dynastie.views.generate_post',name='generate_post'),
url(r'^preview/(\d+)$', 'dynastie.views.preview', name='preview'),
url(r'^tinyMCEExternalList/post/add/(\d+)$', 'dynastie.views.tinymcelist_add', name='tinymce'),
url(r'^tinyMCEExternalList/post/edit/(\d+)$', 'dynastie.views.tinymcelist_edit', name='tinymce'),
dynastie/views.py
498498
499499
500500
501
501
502502
503503
504504
......
528528
529529
530530
531
531
532532
533533
534534
......
544544
545545
546546
547
547
548548
549549
550550
......
588588
589589
590590
591
591
592592
593593
594594
......
601601
602602
603603
604
604
605605
606606
607607
......
649649
650650
651651
652
652
653
654
655
656
657
658
659
660
653661
654662
655663
......
708716
709717
710718
711
719
712720
713721
714722
......
721729
722730
723731
724
732
725733
726734
727735
return render(request, 'add_post.html', {
'form': form, 'blog_id' : blog_id,
'all_tags' : Tag.objects.all(),
'all_tags' : Tag.objects.all().order_by('name'),
'editor' : 'html'
})
if 'cancel' in request.POST:
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
form = PostForm(instance=post, initial={'text_tags':', '.join((tag.name) for tag in post.tags.all())})
form = PostForm(instance=post, initial={'text_tags':', '.join((tag.name) for tag in post.tags.all().order_by('name'))})
filename = b.src_path + '/_post/' + str(post.pk)
if os.path.exists(filename):
return render(request, 'edit_post.html', {
'form': form, 'post_id' : post_id, 'content' : content,
'blog_id' : blog_id, 'comments' : comment_list,
'all_tags' : Tag.objects.all(),
'all_tags' : Tag.objects.all().order_by('name'),
'editor' : post.get_editor()
})
if 'cancel' in request.POST:
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
form = PostForm(instance=draft, initial={'text_tags':', '.join((tag.name) for tag in draft.tags.all())})
form = PostForm(instance=draft, initial={'text_tags':', '.join((tag.name) for tag in draft.tags.all().order_by('name'))})
filename = b.src_path + '/_draft/' + str(draft.pk)
if os.path.exists(filename):
return render(request, 'edit_draft.html', {
'form': form, 'draft_id' : draft_id, 'content' : content,
'blog_id' : blog_id,
'all_tags' : Tag.objects.all(),
'all_tags' : Tag.objects.all().order_by('name'),
'editor' : draft.get_editor()
})
def generate(request, blog_id):
b,_ = have_I_right(request, blog_id)
report = b.generate()
report = b.generate(request)
return _generate(request, blog_id, report)
@login_required
def generate_post(request, blog_id, post_id):
b,post = have_I_right(request, blog_id, post_id)
report = b.generate_post(request, post)
return _generate(request, blog_id, report)
content = request.POST['content']
if request.POST['editor'] == 'text':
from dynastie.generators import markdown2
content = markdown2.markdown(content)
content = markdown2.markdown(content, extras=['fenced-code-blocks'])
values = {'title' : request.POST['title'], \
'author' : request.user.first_name + ' ' + request.user.last_name, \
if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \
and obj.__module__.endswith("post"):
e = obj()
content = e.preview(b.src_path, values)
content = e.preview(request, b.src_path, values)
break
output = b.output_path

Archive Download the corresponding diff file

Branches

Tags