From e0b8f544ffdc1905da4348572218c5d233e37cfb Mon Sep 17 00:00:00 2001 From: Gregory Soutade Date: Sat, 9 Jan 2016 20:10:27 +0100 Subject: [PATCH] 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 --- ChangeLog | 11 +- README | 4 +- dynastie/generators/generator.py | 4 +- dynastie/generators/index.py | 104 ++++++++------ dynastie/generators/post.py | 16 ++- dynastie/models.py | 37 ++++- dynastie/sites/blog.soutade.fr/_base.html | 3 +- .../sites/blog.soutade.fr/_base_post.html | 3 +- dynastie/sites/blog.soutade.fr/css/blog.css | 128 +++++++++--------- dynastie/static/js/dynastie.js | 6 +- .../plugins/dynastiecolor/editor_plugin.js | 51 +------ dynastie/templates/view_blog.html | 2 +- dynastie/urls.py | 1 + dynastie/views.py | 24 ++-- 14 files changed, 213 insertions(+), 181 deletions(-) mode change 100755 => 120000 dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js diff --git a/ChangeLog b/ChangeLog index 750a91d..f40cdc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,21 @@ -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) diff --git a/README b/README index f68d2ef..2316919 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ 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). @@ -10,7 +10,7 @@ Installation : * 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 diff --git a/dynastie/generators/generator.py b/dynastie/generators/generator.py index 03b2dff..2bb18b5 100755 --- a/dynastie/generators/generator.py +++ b/dynastie/generators/generator.py @@ -57,11 +57,13 @@ class DynastieGenerator: 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 diff --git a/dynastie/generators/index.py b/dynastie/generators/index.py index 5dde0ae..5f342fa 100755 --- a/dynastie/generators/index.py +++ b/dynastie/generators/index.py @@ -31,8 +31,8 @@ from dynastie.generators import markdown2 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, @@ -53,6 +53,7 @@ class Index(DynastieGenerator): self.filename = 'index' self.dirname = '' self.blog = None + self.parent_posts = [] self.resetCounters() @@ -143,7 +144,8 @@ class Index(DynastieGenerator): nav = nav + href + str(self.cur_page+1) + '.html">Next > ' nav = nav + href + str(self.nb_pages-1) + '.html">Last >>' - new_dom = parseString('') + s = '' + new_dom = parseString(s.encode('utf-8')) new_node = new_dom.getElementsByTagName('div')[0] res = new_node.cloneNode(True) root.replaceChild(res, node) @@ -230,23 +232,45 @@ class Index(DynastieGenerator): 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('') + + if end < start: + self.addError('Invalid 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 @@ -255,29 +279,33 @@ class Index(DynastieGenerator): 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'} @@ -286,7 +314,8 @@ class Index(DynastieGenerator): 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) @@ -302,32 +331,26 @@ class Index(DynastieGenerator): 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 @@ -544,6 +567,7 @@ class Index(DynastieGenerator): 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 diff --git a/dynastie/generators/post.py b/dynastie/generators/post.py index 5c48f80..5627b93 100755 --- a/dynastie/generators/post.py +++ b/dynastie/generators/post.py @@ -217,6 +217,7 @@ class Post(Index): self.blog = blog + self.parent_posts = [] posts = Post.objects.all() return self._generate(blog, src, output, posts) @@ -230,26 +231,30 @@ class Post(Index): 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'
' + post_content + u'
' + 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 @@ -258,7 +263,8 @@ class Post(Index): # 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') diff --git a/dynastie/models.py b/dynastie/models.py index ffab2a6..7d76ed2 100755 --- a/dynastie/models.py +++ b/dynastie/models.py @@ -171,8 +171,9 @@ class Blog(models.Model): if errors: raise Exception(errors) - def generate(self): - self.report = '

Generation of ' + datetime.now().strftime("%d/%m/%Y at %H:%M:%S") + '
\n' + def generate(self, request): + start_time = datetime.now() + self.report = '' self.load_generators() self.copytree(self.src_path, self.output_path) generated = [] @@ -190,7 +191,33 @@ class Blog(models.Model): if not r is None: self.report = self.report + '
\n' + r - return self.report + duration = datetime.now() - start_time + t = '

Generation of ' + start_time.strftime("%d/%m/%Y at %H:%M:%S") + '
\n' + t = t + 'Duration ' + str(duration) + '

\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 = '

Generation of ' + start_time.strftime("%d/%m/%Y at %H:%M:%S") + ' post ' + str(post.id) + '
\n' + t = t + 'Duration ' + str(duration) + '

\n' + return t + self.report class Editor(models.Model): name = models.CharField(max_length=255, unique=True) @@ -443,6 +470,10 @@ def delete_tag_signal(sender, **kwargs): 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'] diff --git a/dynastie/sites/blog.soutade.fr/_base.html b/dynastie/sites/blog.soutade.fr/_base.html index 9da6c73..89a077b 100755 --- a/dynastie/sites/blog.soutade.fr/_base.html +++ b/dynastie/sites/blog.soutade.fr/_base.html @@ -77,6 +77,7 @@
diff --git a/dynastie/sites/blog.soutade.fr/_base_post.html b/dynastie/sites/blog.soutade.fr/_base_post.html index 3110b9c..f01e26e 100644 --- a/dynastie/sites/blog.soutade.fr/_base_post.html +++ b/dynastie/sites/blog.soutade.fr/_base_post.html @@ -78,6 +78,7 @@
diff --git a/dynastie/sites/blog.soutade.fr/css/blog.css b/dynastie/sites/blog.soutade.fr/css/blog.css index 0d2dbd9..7889e30 100755 --- a/dynastie/sites/blog.soutade.fr/css/blog.css +++ b/dynastie/sites/blog.soutade.fr/css/blog.css @@ -341,13 +341,13 @@ a img .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 @@ -463,68 +463,68 @@ ul li } /* 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 { diff --git a/dynastie/static/js/dynastie.js b/dynastie/static/js/dynastie.js index e1d6017..aeeeaa4 100755 --- a/dynastie/static/js/dynastie.js +++ b/dynastie/static/js/dynastie.js @@ -3,7 +3,7 @@ tinyMCE.init({ // 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 : "", @@ -14,7 +14,7 @@ tinyMCE.init({ // 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", @@ -85,4 +85,4 @@ function switchEditor() help.style.display="block"; // tinymce.execCommand('mceToggleEditor',false,'content'); } -} \ No newline at end of file +} diff --git a/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js b/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js deleted file mode 100755 index 40ac9fb..0000000 --- a/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * editor_plugin_src.js - * - * Copyright 2012, Grégory Soutadé - * Released under LGPL License. - * - */ - -(function() { - tinymce.create('tinymce.plugins.DynastieColor', { - init : function(ed, url) { - var t = this, css = tinymce.explode(ed.settings.content_css); - - t.editor = ed; - - // Force absolute CSS urls - tinymce.each(css, function(u, k) { - css[k] = ed.documentBaseURI.toAbsolute(u); - }); - - ed.addCommand('mceDynastieColor', function() { - ed.windowManager.open({ - file : ed.getParam("plugin_dynastiecolor_pageurl", url + "/dynastiecolor.html"), - width : parseInt(ed.getParam("plugin_dynastiecolor_width", "700")), - height : parseInt(ed.getParam("plugin_dynastiecolor_height", "800")), - resizable : "yes", - scrollbars : "yes", - popup_css : css ? css.join(',') : ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css"), - }, { - base : ed.documentBaseURI.getURI() - }); - }); - - ed.addButton('dynastiecolor', {title : 'Insert code', cmd : 'mceDynastieColor', image : url + "/img/dynastiecolor.png"}); - }, - - getInfo : function() { - return { - longname : 'DynastieColor', - author : 'Grégory Soutadé', - authorurl : 'http://soutade.fr', - infourl : 'http://indefero.soutade.fr/p/dynastie', - version : tinymce.majorVersion + "." + tinymce.minorVersion - }; - } - }); - - // Register plugin - tinymce.PluginManager.add('dynastiecolor', tinymce.plugins.DynastieColor); -})(); \ No newline at end of file diff --git a/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js b/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js new file mode 120000 index 0000000..3a96ace --- /dev/null +++ b/dynastie/static/js/tinymce/jscripts/tiny_mce/plugins/dynastiecolor/editor_plugin.js @@ -0,0 +1 @@ +editor_plugin_src.js \ No newline at end of file diff --git a/dynastie/templates/view_blog.html b/dynastie/templates/view_blog.html index 84f1e2b..c20939a 100755 --- a/dynastie/templates/view_blog.html +++ b/dynastie/templates/view_blog.html @@ -23,7 +23,7 @@ Drafts {% for draft in drafts %} - + {% endfor %}
{{ draft.id }}{{ draft.title }}{{ draft.creation_date }}{{ draft.modification_date }}Delete
{{ draft.id }}{{ draft.title }}{{ draft.category.name }}{{ draft.creation_date }}{{ draft.modification_date }}Delete

{% endif %} diff --git a/dynastie/urls.py b/dynastie/urls.py index d70ec25..1e2203f 100755 --- a/dynastie/urls.py +++ b/dynastie/urls.py @@ -47,6 +47,7 @@ urlpatterns = patterns('', 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'), diff --git a/dynastie/views.py b/dynastie/views.py index 3215659..c83d8c5 100755 --- a/dynastie/views.py +++ b/dynastie/views.py @@ -498,7 +498,7 @@ def add_post(request, blog_id): 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' }) @@ -528,7 +528,7 @@ def edit_post(request, post_id): 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): @@ -544,7 +544,7 @@ def edit_post(request, post_id): 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() }) @@ -588,7 +588,7 @@ def edit_draft(request, draft_id): 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): @@ -601,7 +601,7 @@ def edit_draft(request, draft_id): 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() }) @@ -649,7 +649,15 @@ def _generate(request, blog_id, report): 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) @@ -708,7 +716,7 @@ def preview(request, blog_id): 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, \ @@ -721,7 +729,7 @@ def preview(request, blog_id): 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