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
|
from md_importer.importer import (
DEFAULT_LANG,
DEFAULT_TEMPLATE,
logger,
)
from md_importer.importer.tools import remove_leading_and_trailing_slash
from developer_portal.models import RawHtml
from cms.api import create_page, add_plugin
from cms.models import Page
from cms.utils.page_resolver import get_page_from_path
from djangocms_text_ckeditor.html import clean_html
from bs4 import BeautifulSoup
import re
import os
class ParentNotFoundException(Exception):
def __init__(self, parent_url):
self.parent_url = parent_url
def __str__(self):
return repr(self.parent_url)
class ArticlePage:
def _text_plugin_needs_update(self, html):
if _compare_html(html, self.draft_text_plugin.body):
return False
if self.text_plugin and _compare_html(html, self.text_plugin.body):
return False
return True
def update(self, title, full_url, menu_title=None, in_navigation=True,
html=None, template=None):
if self.draft.get_title() != title:
self.draft.title = title
if self.draft.get_menu_title() != menu_title:
self.draft.menu_title = menu_title
if self.draft.in_navigation != in_navigation:
self.draft.in_navigation = in_navigation
if self.draft.template != template:
self.draft.template = template
if html:
if self.page:
self.text_plugin = find_text_plugin(self.page)
if self._text_plugin_needs_update(html):
self.draft_text_plugin.body = html
self.draft_text_plugin.save()
else:
# Reset draft
self.draft.revert(DEFAULT_LANG)
def __init__(self, title, full_url, menu_title=None, in_navigation=True,
html=None, template=DEFAULT_TEMPLATE):
self.page = None
self.draft = None
self.draft_text_plugin = None
self.text_plugin = None
self.full_url = full_url
self.title = title
self.menu_title = menu_title
self.in_navigation = in_navigation
self.template = template
# First check if pages already exist.
self.draft = find_page(full_url, draft=True)
if not self.draft:
parent = _find_parent(full_url)
if not parent:
raise ParentNotFoundException(
'Parent for {} not found.'.format(full_url))
slug = os.path.basename(full_url)
self.draft = create_page(
title=title, template=template, language=DEFAULT_LANG,
slug=slug, parent=parent, menu_title=menu_title,
in_navigation=in_navigation, position='last-child')
else:
remove_superfluous_placeholders(self.draft)
remove_superfluous_plugins(self.draft)
add_rawhtml_plugin(self.draft)
self.draft_text_plugin = find_text_plugin(self.draft)
self.update(title, full_url, menu_title, in_navigation, html,
template)
def publish(self):
if self.draft.is_dirty(DEFAULT_LANG):
self.draft.publish(DEFAULT_LANG)
if self.draft.get_public_object():
self.page = self.draft.get_public_object()
class IndexPage(ArticlePage):
def __init__(self, title, full_url, menu_title='Overview',
in_navigation=True, html='', template=DEFAULT_TEMPLATE):
self.imported_articles = []
self.origin = ''
ArticlePage.__init__(self, title, full_url, menu_title,
in_navigation, html, template)
self.publish()
def add_imported_articles(self, imported_articles, origin):
self.imported_articles = imported_articles
self.origin = origin
list_pages = u''
for article in [a for a
in self.imported_articles
if a.full_url.startswith(self.full_url)]:
list_pages += u'<li><a href=\"{}\">{}</a></li>'.format(
unicode(os.path.basename(article.full_url)),
article.title)
html = (
u'<div class=\"row\"><div class=\"eight-col\">\n'
'<p>This section contains documentation for the '
'Snappy project.</p>'
'<p><ul class=\"list-ubuntu\">{}</ul></p>\n'
'<p>Auto-imported from <a '
'href=\"{}\">{}</a>.</p>\n'
'</div></div>'.format(list_pages, self.origin, self.origin))
self.update(self.title, self.full_url, self.menu_title,
self.in_navigation, html, self.template)
self.publish()
def _compare_html(html_a, html_b):
soup_a = BeautifulSoup(html_a, 'html5lib')
soup_b = BeautifulSoup(html_b, 'html5lib')
return (clean_html(soup_a.prettify()) == clean_html(soup_b.prettify()))
def slugify(filename):
return os.path.basename(filename).replace('.md', '').replace('.html', '')
def clean_url(url):
return remove_leading_and_trailing_slash(
re.sub(
r'^\/None|{}\/'.format(DEFAULT_LANG),
'',
url))
def find_page(url, draft=False):
page = get_page_from_path(clean_url(url), draft)
if page and draft and not page.publisher_is_draft:
return page.get_draft_object()
return page
def _find_parent(full_url):
parent_url = os.path.dirname(full_url)
if not parent_url:
root = Page.objects.get_home()
if not root:
return None
return root
parent = get_page_from_path(parent_url, draft=True)
if not parent:
logger.error('Parent {} not found.'.format(parent_url))
return None
return parent
# More than one placeholder -> old style page
def remove_superfluous_placeholders(page):
if page.placeholders.count() > 1:
for placeholder in page.placeholders.all()[1:]:
placeholder.delete()
return page.placeholders.all()[0]
def remove_superfluous_plugins(page):
placeholder = page.placeholders.all()[0]
plugins = placeholder.get_plugins()
if plugins.count() >= 1:
for plugin in plugins[1:]:
plugin.delete()
if plugins.count() == 1 and \
type(plugins[0].get_plugin_instance()[0]) != RawHtml:
plugins[0].delete()
def add_rawhtml_plugin(page):
placeholder = page.placeholders.all()[0]
if not placeholder.get_plugins().count():
add_plugin(
placeholder, 'RawHtmlPlugin', DEFAULT_LANG,
body='')
def find_text_plugin(page):
if not page:
return None
placeholders = page.placeholders.all()
if not placeholders:
return None
# We create the page, so we know there's just one placeholder
plugins = placeholders[0].get_plugins()
return plugins[0].get_plugin_instance()[0]
|